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