diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 156 |
1 files changed, 90 insertions, 66 deletions
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 8e85eff..d569827 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -22,14 +22,6 @@ using namespace llvm; -const TargetRegisterInfo *DwarfExpression::getTRI() const { - return AP.TM.getSubtargetImpl()->getRegisterInfo(); -} - -unsigned DwarfExpression::getDwarfVersion() const { - return AP.getDwarfDebug()->getDwarfVersion(); -} - void DwarfExpression::AddReg(int DwarfReg, const char *Comment) { assert(DwarfReg >= 0 && "invalid negative dwarf register number"); if (DwarfReg < 32) { @@ -73,26 +65,34 @@ void DwarfExpression::AddShr(unsigned ShiftBy) { EmitOp(dwarf::DW_OP_shr); } -bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) { - int DwarfReg = getTRI()->getDwarfRegNum(MachineReg, false); - if (DwarfReg < 0) - return false; +void DwarfExpression::AddOpStackValue() { + if (DwarfVersion >= 4) + EmitOp(dwarf::DW_OP_stack_value); +} +bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) { if (isFrameRegister(MachineReg)) { // If variable offset is based in frame register then use fbreg. EmitOp(dwarf::DW_OP_fbreg); EmitSigned(Offset); - } else { - AddRegIndirect(DwarfReg, Offset); + return true; } + + int DwarfReg = TRI.getDwarfRegNum(MachineReg, false); + if (DwarfReg < 0) + return false; + + AddRegIndirect(DwarfReg, Offset); return true; } bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits, unsigned PieceOffsetInBits) { - const TargetRegisterInfo *TRI = getTRI(); - int Reg = TRI->getDwarfRegNum(MachineReg, false); + if (!TRI.isPhysicalRegister(MachineReg)) + return false; + + int Reg = TRI.getDwarfRegNum(MachineReg, false); // If this is a valid register number, emit it. if (Reg >= 0) { @@ -104,12 +104,12 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg, // Walk up the super-register chain until we find a valid number. // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0. - for (MCSuperRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) { - Reg = TRI->getDwarfRegNum(*SR, false); + for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { + Reg = TRI.getDwarfRegNum(*SR, false); if (Reg >= 0) { - unsigned Idx = TRI->getSubRegIndex(*SR, MachineReg); - unsigned Size = TRI->getSubRegIdxSize(Idx); - unsigned RegOffset = TRI->getSubRegIdxOffset(Idx); + unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); + unsigned Size = TRI.getSubRegIdxSize(Idx); + unsigned RegOffset = TRI.getSubRegIdxOffset(Idx); AddReg(Reg, "super-register"); if (PieceOffsetInBits == RegOffset) { AddOpPiece(Size, RegOffset); @@ -133,15 +133,15 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg, // efficient DW_OP_piece. unsigned CurPos = PieceOffsetInBits; // The size of the register in bits, assuming 8 bits per byte. - unsigned RegSize = TRI->getMinimalPhysRegClass(MachineReg)->getSize() * 8; + unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8; // Keep track of the bits in the register we already emitted, so we // can avoid emitting redundant aliasing subregs. SmallBitVector Coverage(RegSize, false); - for (MCSubRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) { - unsigned Idx = TRI->getSubRegIndex(MachineReg, *SR); - unsigned Size = TRI->getSubRegIdxSize(Idx); - unsigned Offset = TRI->getSubRegIdxOffset(Idx); - Reg = TRI->getDwarfRegNum(*SR, false); + for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { + unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR); + unsigned Size = TRI.getSubRegIdxSize(Idx); + unsigned Offset = TRI.getSubRegIdxOffset(Idx); + Reg = TRI.getDwarfRegNum(*SR, false); // Intersection between the bits we already emitted and the bits // covered by this subregister. @@ -177,16 +177,14 @@ void DwarfExpression::AddSignedConstant(int Value) { // value, so the producers and consumers started to rely on heuristics // to disambiguate the value vs. location status of the expression. // See PR21176 for more details. - if (getDwarfVersion() >= 4) - EmitOp(dwarf::DW_OP_stack_value); + AddOpStackValue(); } void DwarfExpression::AddUnsignedConstant(unsigned Value) { EmitOp(dwarf::DW_OP_constu); EmitUnsigned(Value); // cf. comment in DwarfExpression::AddSignedConstant(). - if (getDwarfVersion() >= 4) - EmitOp(dwarf::DW_OP_stack_value); + AddOpStackValue(); } static unsigned getOffsetOrZero(unsigned OffsetInBits, @@ -197,64 +195,90 @@ static unsigned getOffsetOrZero(unsigned OffsetInBits, return OffsetInBits; } -bool DwarfExpression::AddMachineRegExpression(DIExpression Expr, +bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr, unsigned MachineReg, unsigned PieceOffsetInBits) { - unsigned N = Expr.getNumElements(); - unsigned I = 0; - bool ValidReg = false; + auto I = Expr->expr_op_begin(); + auto E = Expr->expr_op_end(); + if (I == E) + return AddMachineRegPiece(MachineReg); + // Pattern-match combinations for which more efficient representations exist // first. - if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_piece) { - unsigned SizeOfByte = 8; - unsigned OffsetInBits = Expr.getElement(1) * SizeOfByte; - unsigned SizeInBits = Expr.getElement(2) * SizeOfByte; - ValidReg = - AddMachineRegPiece(MachineReg, SizeInBits, - getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); - I = 3; - } else if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_plus && - Expr.getElement(2) == dwarf::DW_OP_deref) { - // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. - unsigned Offset = Expr.getElement(1); - ValidReg = AddMachineRegIndirect(MachineReg, Offset); - I = 3; - } else if (N >= 1 && Expr.getElement(0) == dwarf::DW_OP_deref) { - // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. - ValidReg = AddMachineRegIndirect(MachineReg); - I = 1; - } else - ValidReg = AddMachineRegPiece(MachineReg); + bool ValidReg = false; + switch (I->getOp()) { + case dwarf::DW_OP_bit_piece: { + unsigned OffsetInBits = I->getArg(0); + unsigned SizeInBits = I->getArg(1); + // Piece always comes at the end of the expression. + return AddMachineRegPiece(MachineReg, SizeInBits, + getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); + } + case dwarf::DW_OP_plus: { + auto N = I.getNext(); + unsigned Offset = I->getArg(0); + // First combine all DW_OP_plus until we hit either a DW_OP_deref or a + // DW_OP_bit_piece + while (N != E && N->getOp() == dwarf::DW_OP_plus) { + Offset += N->getArg(0); + ++I; + N = I.getNext(); + } + if (N != E && N->getOp() == dwarf::DW_OP_deref) { + // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. + ValidReg = AddMachineRegIndirect(MachineReg, Offset); + std::advance(I, 2); + } else { + assert ((N == E) || (N->getOp() == dwarf::DW_OP_bit_piece)); + if (Offset == 0) { + ValidReg = AddMachineRegPiece(MachineReg); + } else { + ValidReg = AddMachineRegIndirect(MachineReg, Offset); + AddOpStackValue(); + } + ++I; + } + break; + } + case dwarf::DW_OP_deref: { + // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. + ValidReg = AddMachineRegIndirect(MachineReg); + ++I; + break; + } + default: + llvm_unreachable("unsupported operand"); + } if (!ValidReg) return false; // Emit remaining elements of the expression. - AddExpression(Expr, I); + AddExpression(I, E, PieceOffsetInBits); + return true; } -void DwarfExpression::AddExpression(DIExpression Expr, unsigned I, +void DwarfExpression::AddExpression(DIExpression::expr_op_iterator I, + DIExpression::expr_op_iterator E, unsigned PieceOffsetInBits) { - unsigned N = Expr.getNumElements(); - for (; I < N; ++I) { - switch (Expr.getElement(I)) { - case dwarf::DW_OP_piece: { - unsigned SizeOfByte = 8; - unsigned OffsetInBits = Expr.getElement(++I) * SizeOfByte; - unsigned SizeInBits = Expr.getElement(++I) * SizeOfByte; + for (; I != E; ++I) { + switch (I->getOp()) { + case dwarf::DW_OP_bit_piece: { + unsigned OffsetInBits = I->getArg(0); + unsigned SizeInBits = I->getArg(1); AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); break; } case dwarf::DW_OP_plus: EmitOp(dwarf::DW_OP_plus_uconst); - EmitUnsigned(Expr.getElement(++I)); + EmitUnsigned(I->getArg(0)); break; case dwarf::DW_OP_deref: EmitOp(dwarf::DW_OP_deref); break; default: - llvm_unreachable("unhandled opcode found in DIExpression"); + llvm_unreachable("unhandled opcode found in expression"); } } } |