1*9880d681SAndroid Build Coastguard Worker //===-- llvm/CodeGen/DebugLocEntry.h - Entry in debug_loc list -*- C++ -*--===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H 11*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker #include "DebugLocStream.h" 14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MachineLocation.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h" 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker namespace llvm { 21*9880d681SAndroid Build Coastguard Worker class AsmPrinter; 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker /// \brief This struct describes location entries emitted in the .debug_loc 24*9880d681SAndroid Build Coastguard Worker /// section. 25*9880d681SAndroid Build Coastguard Worker class DebugLocEntry { 26*9880d681SAndroid Build Coastguard Worker /// Begin and end symbols for the address range that this location is valid. 27*9880d681SAndroid Build Coastguard Worker const MCSymbol *Begin; 28*9880d681SAndroid Build Coastguard Worker const MCSymbol *End; 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker public: 31*9880d681SAndroid Build Coastguard Worker /// \brief A single location or constant. 32*9880d681SAndroid Build Coastguard Worker struct Value { ValueValue33*9880d681SAndroid Build Coastguard Worker Value(const DIExpression *Expr, int64_t i) 34*9880d681SAndroid Build Coastguard Worker : Expression(Expr), EntryKind(E_Integer) { 35*9880d681SAndroid Build Coastguard Worker Constant.Int = i; 36*9880d681SAndroid Build Coastguard Worker } ValueValue37*9880d681SAndroid Build Coastguard Worker Value(const DIExpression *Expr, const ConstantFP *CFP) 38*9880d681SAndroid Build Coastguard Worker : Expression(Expr), EntryKind(E_ConstantFP) { 39*9880d681SAndroid Build Coastguard Worker Constant.CFP = CFP; 40*9880d681SAndroid Build Coastguard Worker } ValueValue41*9880d681SAndroid Build Coastguard Worker Value(const DIExpression *Expr, const ConstantInt *CIP) 42*9880d681SAndroid Build Coastguard Worker : Expression(Expr), EntryKind(E_ConstantInt) { 43*9880d681SAndroid Build Coastguard Worker Constant.CIP = CIP; 44*9880d681SAndroid Build Coastguard Worker } ValueValue45*9880d681SAndroid Build Coastguard Worker Value(const DIExpression *Expr, MachineLocation Loc) 46*9880d681SAndroid Build Coastguard Worker : Expression(Expr), EntryKind(E_Location), Loc(Loc) { 47*9880d681SAndroid Build Coastguard Worker assert(cast<DIExpression>(Expr)->isValid()); 48*9880d681SAndroid Build Coastguard Worker } 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker /// Any complex address location expression for this Value. 51*9880d681SAndroid Build Coastguard Worker const DIExpression *Expression; 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker /// Type of entry that this represents. 54*9880d681SAndroid Build Coastguard Worker enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt }; 55*9880d681SAndroid Build Coastguard Worker enum EntryType EntryKind; 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker /// Either a constant, 58*9880d681SAndroid Build Coastguard Worker union { 59*9880d681SAndroid Build Coastguard Worker int64_t Int; 60*9880d681SAndroid Build Coastguard Worker const ConstantFP *CFP; 61*9880d681SAndroid Build Coastguard Worker const ConstantInt *CIP; 62*9880d681SAndroid Build Coastguard Worker } Constant; 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker // Or a location in the machine frame. 65*9880d681SAndroid Build Coastguard Worker MachineLocation Loc; 66*9880d681SAndroid Build Coastguard Worker isLocationValue67*9880d681SAndroid Build Coastguard Worker bool isLocation() const { return EntryKind == E_Location; } isIntValue68*9880d681SAndroid Build Coastguard Worker bool isInt() const { return EntryKind == E_Integer; } isConstantFPValue69*9880d681SAndroid Build Coastguard Worker bool isConstantFP() const { return EntryKind == E_ConstantFP; } isConstantIntValue70*9880d681SAndroid Build Coastguard Worker bool isConstantInt() const { return EntryKind == E_ConstantInt; } getIntValue71*9880d681SAndroid Build Coastguard Worker int64_t getInt() const { return Constant.Int; } getConstantFPValue72*9880d681SAndroid Build Coastguard Worker const ConstantFP *getConstantFP() const { return Constant.CFP; } getConstantIntValue73*9880d681SAndroid Build Coastguard Worker const ConstantInt *getConstantInt() const { return Constant.CIP; } getLocValue74*9880d681SAndroid Build Coastguard Worker MachineLocation getLoc() const { return Loc; } isBitPieceValue75*9880d681SAndroid Build Coastguard Worker bool isBitPiece() const { return getExpression()->isBitPiece(); } getExpressionValue76*9880d681SAndroid Build Coastguard Worker const DIExpression *getExpression() const { return Expression; } 77*9880d681SAndroid Build Coastguard Worker friend bool operator==(const Value &, const Value &); 78*9880d681SAndroid Build Coastguard Worker friend bool operator<(const Value &, const Value &); dumpValue79*9880d681SAndroid Build Coastguard Worker void dump() const { 80*9880d681SAndroid Build Coastguard Worker if (isLocation()) { 81*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " "; 82*9880d681SAndroid Build Coastguard Worker if (Loc.isIndirect()) 83*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << '+' << Loc.getOffset(); 84*9880d681SAndroid Build Coastguard Worker llvm::dbgs() << "} "; 85*9880d681SAndroid Build Coastguard Worker } 86*9880d681SAndroid Build Coastguard Worker else if (isConstantInt()) 87*9880d681SAndroid Build Coastguard Worker Constant.CIP->dump(); 88*9880d681SAndroid Build Coastguard Worker else if (isConstantFP()) 89*9880d681SAndroid Build Coastguard Worker Constant.CFP->dump(); 90*9880d681SAndroid Build Coastguard Worker if (Expression) 91*9880d681SAndroid Build Coastguard Worker Expression->dump(); 92*9880d681SAndroid Build Coastguard Worker } 93*9880d681SAndroid Build Coastguard Worker }; 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker private: 96*9880d681SAndroid Build Coastguard Worker /// A nonempty list of locations/constants belonging to this entry, 97*9880d681SAndroid Build Coastguard Worker /// sorted by offset. 98*9880d681SAndroid Build Coastguard Worker SmallVector<Value, 1> Values; 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker public: DebugLocEntry(const MCSymbol * B,const MCSymbol * E,Value Val)101*9880d681SAndroid Build Coastguard Worker DebugLocEntry(const MCSymbol *B, const MCSymbol *E, Value Val) 102*9880d681SAndroid Build Coastguard Worker : Begin(B), End(E) { 103*9880d681SAndroid Build Coastguard Worker Values.push_back(std::move(Val)); 104*9880d681SAndroid Build Coastguard Worker } 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker /// \brief If this and Next are describing different pieces of the same 107*9880d681SAndroid Build Coastguard Worker /// variable, merge them by appending Next's values to the current 108*9880d681SAndroid Build Coastguard Worker /// list of values. 109*9880d681SAndroid Build Coastguard Worker /// Return true if the merge was successful. 110*9880d681SAndroid Build Coastguard Worker bool MergeValues(const DebugLocEntry &Next); 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker /// \brief Attempt to merge this DebugLocEntry with Next and return 113*9880d681SAndroid Build Coastguard Worker /// true if the merge was successful. Entries can be merged if they 114*9880d681SAndroid Build Coastguard Worker /// share the same Loc/Constant and if Next immediately follows this 115*9880d681SAndroid Build Coastguard Worker /// Entry. MergeRanges(const DebugLocEntry & Next)116*9880d681SAndroid Build Coastguard Worker bool MergeRanges(const DebugLocEntry &Next) { 117*9880d681SAndroid Build Coastguard Worker // If this and Next are describing the same variable, merge them. 118*9880d681SAndroid Build Coastguard Worker if ((End == Next.Begin && Values == Next.Values)) { 119*9880d681SAndroid Build Coastguard Worker End = Next.End; 120*9880d681SAndroid Build Coastguard Worker return true; 121*9880d681SAndroid Build Coastguard Worker } 122*9880d681SAndroid Build Coastguard Worker return false; 123*9880d681SAndroid Build Coastguard Worker } 124*9880d681SAndroid Build Coastguard Worker getBeginSym()125*9880d681SAndroid Build Coastguard Worker const MCSymbol *getBeginSym() const { return Begin; } getEndSym()126*9880d681SAndroid Build Coastguard Worker const MCSymbol *getEndSym() const { return End; } getValues()127*9880d681SAndroid Build Coastguard Worker ArrayRef<Value> getValues() const { return Values; } addValues(ArrayRef<DebugLocEntry::Value> Vals)128*9880d681SAndroid Build Coastguard Worker void addValues(ArrayRef<DebugLocEntry::Value> Vals) { 129*9880d681SAndroid Build Coastguard Worker Values.append(Vals.begin(), Vals.end()); 130*9880d681SAndroid Build Coastguard Worker sortUniqueValues(); 131*9880d681SAndroid Build Coastguard Worker assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value V){ 132*9880d681SAndroid Build Coastguard Worker return V.isBitPiece(); 133*9880d681SAndroid Build Coastguard Worker }) && "value must be a piece"); 134*9880d681SAndroid Build Coastguard Worker } 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker // \brief Sort the pieces by offset. 137*9880d681SAndroid Build Coastguard Worker // Remove any duplicate entries by dropping all but the first. sortUniqueValues()138*9880d681SAndroid Build Coastguard Worker void sortUniqueValues() { 139*9880d681SAndroid Build Coastguard Worker std::sort(Values.begin(), Values.end()); 140*9880d681SAndroid Build Coastguard Worker Values.erase( 141*9880d681SAndroid Build Coastguard Worker std::unique( 142*9880d681SAndroid Build Coastguard Worker Values.begin(), Values.end(), [](const Value &A, const Value &B) { 143*9880d681SAndroid Build Coastguard Worker return A.getExpression() == B.getExpression(); 144*9880d681SAndroid Build Coastguard Worker }), 145*9880d681SAndroid Build Coastguard Worker Values.end()); 146*9880d681SAndroid Build Coastguard Worker } 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker /// \brief Lower this entry into a DWARF expression. 149*9880d681SAndroid Build Coastguard Worker void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, 150*9880d681SAndroid Build Coastguard Worker const DIBasicType *BT); 151*9880d681SAndroid Build Coastguard Worker }; 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker /// \brief Compare two Values for equality. 154*9880d681SAndroid Build Coastguard Worker inline bool operator==(const DebugLocEntry::Value &A, 155*9880d681SAndroid Build Coastguard Worker const DebugLocEntry::Value &B) { 156*9880d681SAndroid Build Coastguard Worker if (A.EntryKind != B.EntryKind) 157*9880d681SAndroid Build Coastguard Worker return false; 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Worker if (A.Expression != B.Expression) 160*9880d681SAndroid Build Coastguard Worker return false; 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker switch (A.EntryKind) { 163*9880d681SAndroid Build Coastguard Worker case DebugLocEntry::Value::E_Location: 164*9880d681SAndroid Build Coastguard Worker return A.Loc == B.Loc; 165*9880d681SAndroid Build Coastguard Worker case DebugLocEntry::Value::E_Integer: 166*9880d681SAndroid Build Coastguard Worker return A.Constant.Int == B.Constant.Int; 167*9880d681SAndroid Build Coastguard Worker case DebugLocEntry::Value::E_ConstantFP: 168*9880d681SAndroid Build Coastguard Worker return A.Constant.CFP == B.Constant.CFP; 169*9880d681SAndroid Build Coastguard Worker case DebugLocEntry::Value::E_ConstantInt: 170*9880d681SAndroid Build Coastguard Worker return A.Constant.CIP == B.Constant.CIP; 171*9880d681SAndroid Build Coastguard Worker } 172*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unhandled EntryKind"); 173*9880d681SAndroid Build Coastguard Worker } 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker /// \brief Compare two pieces based on their offset. 176*9880d681SAndroid Build Coastguard Worker inline bool operator<(const DebugLocEntry::Value &A, 177*9880d681SAndroid Build Coastguard Worker const DebugLocEntry::Value &B) { 178*9880d681SAndroid Build Coastguard Worker return A.getExpression()->getBitPieceOffset() < 179*9880d681SAndroid Build Coastguard Worker B.getExpression()->getBitPieceOffset(); 180*9880d681SAndroid Build Coastguard Worker } 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Worker } 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker #endif 185