136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===-- llvm/CodeGen/DebugLocEntry.h - Entry in debug_loc list -*- C++ -*--===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/SmallString.h"
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Constants.h"
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/IR/DebugInfo.h"
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSymbol.h"
16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MachineLocation.h"
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm {
194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarclass AsmPrinter;
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass MDNode;
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// \brief This struct describes location entries emitted in the .debug_loc
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// section.
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass DebugLocEntry {
244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// Begin and end symbols for the address range that this location is valid.
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCSymbol *Begin;
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCSymbol *End;
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinespublic:
294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// \brief A single location or constant.
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  struct Value {
3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value(const MDNode *Var, const MDNode *Expr, int64_t i)
3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        : Variable(Var), Expression(Expr), EntryKind(E_Integer) {
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Constant.Int = i;
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value(const MDNode *Var, const MDNode *Expr, const ConstantFP *CFP)
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        : Variable(Var), Expression(Expr), EntryKind(E_ConstantFP) {
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Constant.CFP = CFP;
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value(const MDNode *Var, const MDNode *Expr, const ConstantInt *CIP)
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        : Variable(Var), Expression(Expr), EntryKind(E_ConstantInt) {
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Constant.CIP = CIP;
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value(const MDNode *Var, const MDNode *Expr, MachineLocation Loc)
4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        : Variable(Var), Expression(Expr), EntryKind(E_Location), Loc(Loc) {
452c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      assert(isa<MDLocalVariable>(Var));
462c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      assert(cast<MDExpression>(Expr)->isValid());
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    /// The variable to which this location entry corresponds.
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MDNode *Variable;
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    /// Any complex address location expression for this Value.
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const MDNode *Expression;
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    /// Type of entry that this represents.
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    enum EntryType EntryKind;
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    /// Either a constant,
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    union {
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int64_t Int;
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const ConstantFP *CFP;
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const ConstantInt *CIP;
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } Constant;
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Or a location in the machine frame.
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineLocation Loc;
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isLocation() const { return EntryKind == E_Location; }
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isInt() const { return EntryKind == E_Integer; }
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isConstantFP() const { return EntryKind == E_ConstantFP; }
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool isConstantInt() const { return EntryKind == E_ConstantInt; }
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    int64_t getInt() const { return Constant.Int; }
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const ConstantFP *getConstantFP() const { return Constant.CFP; }
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const ConstantInt *getConstantInt() const { return Constant.CIP; }
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MachineLocation getLoc() const { return Loc; }
772c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    DIVariable getVariable() const { return cast<MDLocalVariable>(Variable); }
782c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    bool isBitPiece() const { return getExpression()->isBitPiece(); }
792c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    DIExpression getExpression() const {
802c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      return cast_or_null<MDExpression>(Expression);
812c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    }
8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    friend bool operator==(const Value &, const Value &);
8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    friend bool operator<(const Value &, const Value &);
84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesprivate:
8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// A nonempty list of locations/constants belonging to this entry,
8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// sorted by offset.
89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SmallVector<Value, 1> Values;
904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  SmallString<8> DWARFBytes;
914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  SmallVector<std::string, 1> Comments;
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DebugLocEntry(const MCSymbol *B, const MCSymbol *E, Value Val)
9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      : Begin(B), End(E) {
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Values.push_back(std::move(Val));
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// \brief If this and Next are describing different pieces of the same
1004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// variable, merge them by appending Next's values to the current
1014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// list of values.
1024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// Return true if the merge was successful.
10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool MergeValues(const DebugLocEntry &Next) {
10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Begin == Next.Begin) {
1052c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      DIExpression Expr = cast_or_null<MDExpression>(Values[0].Expression);
1062c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      DIVariable Var = cast_or_null<MDLocalVariable>(Values[0].Variable);
1072c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      DIExpression NextExpr =
1082c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar          cast_or_null<MDExpression>(Next.Values[0].Expression);
1092c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      DIVariable NextVar = cast_or_null<MDLocalVariable>(Next.Values[0].Variable);
1102c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      if (Var == NextVar && Expr->isBitPiece() && NextExpr->isBitPiece()) {
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        addValues(Next.Values);
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        End = Next.End;
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return true;
11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Attempt to merge this DebugLocEntry with Next and return
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// true if the merge was successful. Entries can be merged if they
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// share the same Loc/Constant and if Next immediately follows this
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Entry.
12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool MergeRanges(const DebugLocEntry &Next) {
12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If this and Next are describing the same variable, merge them.
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if ((End == Next.Begin && Values == Next.Values)) {
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      End = Next.End;
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCSymbol *getBeginSym() const { return Begin; }
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCSymbol *getEndSym() const { return End; }
13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ArrayRef<Value> getValues() const { return Values; }
13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void addValues(ArrayRef<DebugLocEntry::Value> Vals) {
13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Values.append(Vals.begin(), Vals.end());
13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    sortUniqueValues();
13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value V){
139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return V.isBitPiece();
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }) && "value must be a piece");
14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  // \brief Sort the pieces by offset.
14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Remove any duplicate entries by dropping all but the first.
14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void sortUniqueValues() {
14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::sort(Values.begin(), Values.end());
14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Values.erase(std::unique(Values.begin(), Values.end(),
14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             [](const Value &A, const Value &B) {
14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                   return A.getVariable() == B.getVariable() &&
15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          A.getExpression() == B.getExpression();
15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 }),
15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 Values.end());
15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// \brief Lower this entry into a DWARF expression.
1564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  void finalize(const AsmPrinter &AP,
1574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                const DITypeIdentifierMap &TypeIdentifierMap);
1584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// \brief Return the lowered DWARF expression.
1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  StringRef getDWARFBytes() const { return DWARFBytes; }
1614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  /// \brief Return the assembler comments for the lowered DWARF expression.
1624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  const SmallVectorImpl<std::string> &getComments() const { return Comments; }
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Compare two Values for equality.
16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesinline bool operator==(const DebugLocEntry::Value &A,
16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       const DebugLocEntry::Value &B) {
16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (A.EntryKind != B.EntryKind)
16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (A.Expression != B.Expression)
17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (A.Variable != B.Variable)
17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch (A.EntryKind) {
17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case DebugLocEntry::Value::E_Location:
17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return A.Loc == B.Loc;
18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case DebugLocEntry::Value::E_Integer:
18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return A.Constant.Int == B.Constant.Int;
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case DebugLocEntry::Value::E_ConstantFP:
18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return A.Constant.CFP == B.Constant.CFP;
18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case DebugLocEntry::Value::E_ConstantInt:
18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return A.Constant.CIP == B.Constant.CIP;
18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm_unreachable("unhandled EntryKind");
18837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// \brief Compare two pieces based on their offset.
19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesinline bool operator<(const DebugLocEntry::Value &A,
19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                      const DebugLocEntry::Value &B) {
1932c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  return A.getExpression()->getBitPieceOffset() <
1942c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar         B.getExpression()->getBitPieceOffset();
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
200