llvm.org GIT mirror llvm / a782d2c
Reland "[DwarfDebug] Dump call site debug info" The build failure found after the rL365467 has been resolved. Differential Revision: https://reviews.llvm.org/D60716 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367446 91177308-0d34-0410-b5e6-96231b3b80d8 Djordje Todorovic 2 months ago
23 changed file(s) with 1145 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
47684768 ``DW_OP_entry_value`` may also appear after the ``AsmPrinter`` pass when
47694769 a call site parameter value (``DW_AT_call_site_parameter_value``)
47704770 is represented as entry value of the parameter.
4771 - ``DW_OP_breg`` (or ``DW_OP_bregx``) represents a content on the provided
4772 signed offset of the specified register. The opcode is only generated by the
4773 ``AsmPrinter`` pass to describe call site parameter value which requires an
4774 expression over two registers.
47714775
47724776 DWARF specifies three kinds of simple location descriptions: Register, memory,
47734777 and implicit location descriptions. Note that a location description is
5959
6060 template class SmallVectorImpl;
6161
62 using ParamLoadedValue = std::pair;
63
6264 //---------------------------------------------------------------------------
6365 ///
6466 /// TargetInstrInfo - Interface to description of machine instruction set
16901692 return false;
16911693 }
16921694
1695 /// Produce the expression describing the \p MI loading a value into
1696 /// the parameter's forwarding register.
1697 virtual Optional
1698 describeLoadedValue(const MachineInstr &MI) const;
1699
16931700 private:
16941701 unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
16951702 unsigned CatchRetOpcode;
533533 const MachineFunction &MF) const {
534534 return false;
535535 }
536
537 /// This is a wrapper around getCallPreservedMask().
538 /// Return true if the register is preserved after the call.
539 virtual bool isCalleeSavedPhysReg(unsigned PhysReg,
540 const MachineFunction &MF) const;
536541
537542 /// Prior to adding the live-out mask to a stackmap or patchpoint
538543 /// instruction, provide the target the opportunity to adjust it (mainly to
891891 ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
892892 }
893893
894 DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
895 const DISubprogram &CalleeSP,
896 bool IsTail,
897 const MCExpr *PCOffset) {
894 dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUCallSiteTag(dwarf::Tag Tag) const {
895 bool ApplyGNUExtensions = DD->getDwarfVersion() == 4 && DD->tuneForGDB();
896 if (!ApplyGNUExtensions)
897 return Tag;
898 switch (Tag) {
899 case dwarf::DW_TAG_call_site:
900 return dwarf::DW_TAG_GNU_call_site;
901 case dwarf::DW_TAG_call_site_parameter:
902 return dwarf::DW_TAG_GNU_call_site_parameter;
903 default:
904 llvm_unreachable("unhandled call site tag");
905 }
906 }
907
908 dwarf::Attribute
909 DwarfCompileUnit::getDwarf5OrGNUCallSiteAttr(dwarf::Attribute Attr) const {
910 bool ApplyGNUExtensions = DD->getDwarfVersion() == 4 && DD->tuneForGDB();
911 if (!ApplyGNUExtensions)
912 return Attr;
913 switch (Attr) {
914 case dwarf::DW_AT_call_all_calls:
915 return dwarf::DW_AT_GNU_all_call_sites;
916 case dwarf::DW_AT_call_target:
917 return dwarf::DW_AT_GNU_call_site_target;
918 case dwarf::DW_AT_call_origin:
919 return dwarf::DW_AT_abstract_origin;
920 case dwarf::DW_AT_call_pc:
921 return dwarf::DW_AT_low_pc;
922 case dwarf::DW_AT_call_value:
923 return dwarf::DW_AT_GNU_call_site_value;
924 case dwarf::DW_AT_call_tail_call:
925 return dwarf::DW_AT_GNU_tail_call;
926 default:
927 llvm_unreachable("unhandled call site attribute");
928 }
929 }
930
931 DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
932 DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail,
933 const MCSymbol *PCAddr, const MCExpr *PCOffset, unsigned CallReg) {
898934 // Insert a call site entry DIE within ScopeDIE.
899 DIE &CallSiteDIE =
900 createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr);
901
902 // For the purposes of showing tail call frames in backtraces, a key piece of
903 // information is DW_AT_call_origin, a pointer to the callee DIE.
904 DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP);
905 assert(CalleeDIE && "Could not create DIE for call site entry origin");
906 addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE);
907
908 if (IsTail) {
935 DIE &CallSiteDIE = createAndAddDIE(
936 getDwarf5OrGNUCallSiteTag(dwarf::DW_TAG_call_site), ScopeDIE, nullptr);
937
938 if (CallReg) {
939 // Indirect call.
940 addAddress(CallSiteDIE,
941 getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_target),
942 MachineLocation(CallReg));
943 } else {
944 DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
945 assert(CalleeDIE && "Could not create DIE for call site entry origin");
946 addDIEEntry(CallSiteDIE,
947 getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_origin),
948 *CalleeDIE);
949 }
950
951 if (IsTail)
909952 // Attach DW_AT_call_tail_call to tail calls for standards compliance.
910 addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call);
911 } else {
912 // Attach the return PC to allow the debugger to disambiguate call paths
913 // from one function to another.
953 addFlag(CallSiteDIE,
954 getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_tail_call));
955
956 // Attach the return PC to allow the debugger to disambiguate call paths
957 // from one function to another.
958 if (DD->getDwarfVersion() == 4 && DD->tuneForGDB()) {
959 assert(PCAddr && "Missing PC information for a call");
960 addLabelAddress(CallSiteDIE, dwarf::DW_AT_low_pc, PCAddr);
961 } else if (!IsTail || DD->tuneForGDB()) {
914962 assert(PCOffset && "Missing return PC information for a call");
915963 addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset);
916964 }
965
917966 return CallSiteDIE;
967 }
968
969 void DwarfCompileUnit::constructCallSiteParmEntryDIEs(
970 DIE &CallSiteDIE, SmallVector &Params) {
971 for (const auto &Param : Params) {
972 unsigned Register = Param.getRegister();
973 auto CallSiteDieParam =
974 DIE::get(DIEValueAllocator,
975 getDwarf5OrGNUCallSiteTag(dwarf::DW_TAG_call_site_parameter));
976 insertDIE(CallSiteDieParam);
977 addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
978 MachineLocation(Register));
979
980 DIELoc *Loc = new (DIEValueAllocator) DIELoc;
981 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
982 DwarfExpr.setCallSiteParamValueFlag();
983
984 DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);
985
986 addBlock(*CallSiteDieParam,
987 getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_value),
988 DwarfExpr.finalize());
989
990 CallSiteDIE.addChild(CallSiteDieParam);
991 }
918992 }
919993
920994 DIE *DwarfCompileUnit::constructImportedEntityDIE(
226226
227227 void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
228228
229 /// This takes the official DWARF 5 tag and returns the appropriate
230 /// GNU tag if needed.
231 dwarf::Tag getDwarf5OrGNUCallSiteTag(dwarf::Tag Tag) const;
232 /// This takes the official DWARF 5 attribute and returns the appropriate
233 /// GNU attribute if needed.
234 dwarf::Attribute getDwarf5OrGNUCallSiteAttr(dwarf::Attribute Attr) const;
235
229236 /// Construct a call site entry DIE describing a call within \p Scope to a
230 /// callee described by \p CalleeSP. \p IsTail specifies whether the call is
231 /// a tail call. \p PCOffset must be non-zero for non-tail calls or be the
237 /// callee described by \p CalleeSP.
238 /// \p IsTail specifies whether the call is a tail call.
239 /// \p PCAddr (used for GDB + DWARF 4 tuning) points to the PC value after
240 /// the call instruction.
241 /// \p PCOffset (used for cases other than GDB + DWARF 4 tuning) must be
242 /// non-zero for non-tail calls (in the case of non-gdb tuning, since for
243 /// GDB + DWARF 5 tuning we still generate PC info for tail calls) or be the
232244 /// function-local offset to PC value after the call instruction.
233 DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram &CalleeSP,
234 bool IsTail, const MCExpr *PCOffset);
245 /// \p CallReg is a register location for an indirect call. For direct calls
246 /// the \p CallReg is set to 0.
247 DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,
248 bool IsTail, const MCSymbol *PCAddr,
249 const MCExpr *PCOffset, unsigned CallReg);
250 /// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params
251 /// were collected by the \ref collectCallSiteParameters.
252 /// Note: The order of parameters does not matter, since debuggers recognize
253 /// call site parameters by the DW_AT_location attribute.
254 void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE,
255 SmallVector &Params);
235256
236257 /// Construct import_module DIE.
237258 DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
2525 #include "llvm/ADT/STLExtras.h"
2626 #include "llvm/ADT/SmallVector.h"
2727 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/Statistic.h"
2829 #include "llvm/ADT/Triple.h"
2930 #include "llvm/ADT/Twine.h"
3031 #include "llvm/BinaryFormat/Dwarf.h"
3839 #include "llvm/CodeGen/MachineModuleInfo.h"
3940 #include "llvm/CodeGen/MachineOperand.h"
4041 #include "llvm/CodeGen/TargetInstrInfo.h"
42 #include "llvm/CodeGen/TargetLowering.h"
4143 #include "llvm/CodeGen/TargetRegisterInfo.h"
4244 #include "llvm/CodeGen/TargetSubtargetInfo.h"
4345 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
8284
8385 #define DEBUG_TYPE "dwarfdebug"
8486
87 STATISTIC(NumCSParams, "Number of dbg call site params created");
88
8589 static cl::opt
8690 DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
8791 cl::desc("Disable debug info printing"));
550554 }
551555 }
552556
557 /// Try to interpret values loaded into registers that forward parameters
558 /// for \p CallMI. Store parameters with interpreted value into \p Params.
559 static void collectCallSiteParameters(const MachineInstr *CallMI,
560 ParamSet &Params) {
561 auto *MF = CallMI->getMF();
562 auto CalleesMap = MF->getCallSitesInfo();
563 auto CallFwdRegsInfo = CalleesMap.find(CallMI);
564
565 // There is no information for the call instruction.
566 if (CallFwdRegsInfo == CalleesMap.end())
567 return;
568
569 auto *MBB = CallMI->getParent();
570 const auto &TRI = MF->getSubtarget().getRegisterInfo();
571 const auto &TII = MF->getSubtarget().getInstrInfo();
572 const auto &TLI = MF->getSubtarget().getTargetLowering();
573
574 // Skip the call instruction.
575 auto I = std::next(CallMI->getReverseIterator());
576
577 DenseSet ForwardedRegWorklist;
578 // Add all the forwarding registers into the ForwardedRegWorklist.
579 for (auto ArgReg : CallFwdRegsInfo->second) {
580 bool InsertedReg = ForwardedRegWorklist.insert(ArgReg.Reg).second;
581 assert(InsertedReg && "Single register used to forward two arguments?");
582 }
583
584 // We erase, from the ForwardedRegWorklist, those forwarding registers for
585 // which we successfully describe a loaded value (by using
586 // the describeLoadedValue()). For those remaining arguments in the working
587 // list, for which we do not describe a loaded value by
588 // the describeLoadedValue(), we try to generate an entry value expression
589 // for their call site value desctipion, if the call is within the entry MBB.
590 // The RegsForEntryValues maps a forwarding register into the register holding
591 // the entry value.
592 // TODO: Handle situations when call site parameter value can be described
593 // as the entry value within basic blocks other then the first one.
594 bool ShouldTryEmitEntryVals = MBB->getIterator() == MF->begin();
595 DenseMap RegsForEntryValues;
596
597 // If the MI is an instruction defining a parameter's forwarding register,
598 // add it into the Defs. If the MI clobbers more then one register, we use
599 // the Defs in order to remove all the registers from
600 // the ForwardedRegWorklist, since we do not support such situations now.
601 auto getForwardingRegsDefinedByMI = [&](const MachineInstr &MI,
602 SmallVectorImpl &Defs) {
603 if (MI.isDebugInstr())
604 return;
605
606 for (const MachineOperand &MO : MI.operands()) {
607 if (MO.isReg() && MO.isDef() && TRI->isPhysicalRegister(MO.getReg())) {
608 for (auto FwdReg : ForwardedRegWorklist) {
609 if (TRI->regsOverlap(FwdReg, MO.getReg())) {
610 Defs.push_back(FwdReg);
611 break;
612 }
613 }
614 }
615 }
616 };
617
618 auto finishCallSiteParam = [&](DbgValueLoc DbgLocVal, unsigned Reg) {
619 unsigned FwdReg = Reg;
620 if (ShouldTryEmitEntryVals) {
621 auto EntryValReg = RegsForEntryValues.find(Reg);
622 if (EntryValReg != RegsForEntryValues.end())
623 FwdReg = EntryValReg->second;
624 }
625
626 DbgCallSiteParam CSParm(FwdReg, DbgLocVal);
627 Params.push_back(CSParm);
628 ++NumCSParams;
629 };
630
631 // Search for a loading value in forwaring registers.
632 for (; I != MBB->rend(); ++I) {
633 // If the next instruction is a call we can not interpret parameter's
634 // forwarding registers or we finished the interpretation of all parameters.
635 if (I->isCall())
636 return;
637
638 if (ForwardedRegWorklist.empty())
639 return;
640
641 SmallVector Defs;
642 getForwardingRegsDefinedByMI(*I, Defs);
643 if (Defs.empty())
644 continue;
645
646 // If the MI clobbers more then one forwarding register we must remove
647 // all of them from the working list.
648 for (auto Reg : Defs)
649 ForwardedRegWorklist.erase(Reg);
650 if (I->getNumDefs() != 1)
651 continue;
652 unsigned Reg = Defs[0];
653
654 if (auto ParamValue = TII->describeLoadedValue(*I)) {
655 if (ParamValue->first->isImm()) {
656 unsigned Val = ParamValue->first->getImm();
657 DbgValueLoc DbgLocVal(ParamValue->second, Val);
658 finishCallSiteParam(DbgLocVal, Reg);
659 } else if (ParamValue->first->isReg()) {
660 unsigned RegLoc = ParamValue->first->getReg();
661 unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
662 unsigned FP = TRI->getFrameRegister(*MF);
663 bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP);
664 if (TRI->isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP) {
665 DbgValueLoc DbgLocVal(ParamValue->second,
666 MachineLocation(RegLoc,
667 /*IsIndirect=*/IsSPorFP));
668 finishCallSiteParam(DbgLocVal, Reg);
669 } else if (ShouldTryEmitEntryVals) {
670 ForwardedRegWorklist.insert(RegLoc);
671 RegsForEntryValues[RegLoc] = Reg;
672 }
673 }
674 }
675 }
676
677 // Emit the call site parameter's value as an entry value.
678 if (ShouldTryEmitEntryVals) {
679 // Create an entry value expression where the expression following
680 // the 'DW_OP_entry_value' will be the size of 1 (a register operation).
681 DIExpression *EntryExpr = DIExpression::get(MF->getFunction().getContext(),
682 {dwarf::DW_OP_entry_value, 1});
683 for (auto RegEntry : ForwardedRegWorklist) {
684 unsigned FwdReg = RegEntry;
685 auto EntryValReg = RegsForEntryValues.find(RegEntry);
686 if (EntryValReg != RegsForEntryValues.end())
687 FwdReg = EntryValReg->second;
688
689 DbgValueLoc DbgLocVal(EntryExpr, MachineLocation(RegEntry));
690 DbgCallSiteParam CSParm(FwdReg, DbgLocVal);
691 Params.push_back(CSParm);
692 ++NumCSParams;
693 }
694 }
695 }
696
553697 void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
554698 DwarfCompileUnit &CU, DIE &ScopeDIE,
555699 const MachineFunction &MF) {
562706 // for both tail and non-tail calls. Don't use DW_AT_call_all_source_calls
563707 // because one of its requirements is not met: call site entries for
564708 // optimized-out calls are elided.
565 CU.addFlag(ScopeDIE, dwarf::DW_AT_call_all_calls);
709 CU.addFlag(ScopeDIE,
710 CU.getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_all_calls));
566711
567712 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
568713 assert(TII && "TargetInstrInfo not found: cannot label tail calls");
714 bool ApplyGNUExtensions = getDwarfVersion() == 4 && tuneForGDB();
569715
570716 // Emit call site entries for each call or tail call in the function.
571717 for (const MachineBasicBlock &MBB : MF) {
580726 return;
581727
582728 // If this is a direct call, find the callee's subprogram.
729 // In the case of an indirect call find the register that holds
730 // the callee.
583731 const MachineOperand &CalleeOp = MI.getOperand(0);
584 if (!CalleeOp.isGlobal())
732 if (!CalleeOp.isGlobal() && !CalleeOp.isReg())
585733 continue;
586 const Function *CalleeDecl = dyn_cast(CalleeOp.getGlobal());
587 if (!CalleeDecl || !CalleeDecl->getSubprogram())
588 continue;
734
735 unsigned CallReg = 0;
736 const DISubprogram *CalleeSP = nullptr;
737 const Function *CalleeDecl = nullptr;
738 if (CalleeOp.isReg()) {
739 CallReg = CalleeOp.getReg();
740 if (!CallReg)
741 continue;
742 } else {
743 CalleeDecl = dyn_cast(CalleeOp.getGlobal());
744 if (!CalleeDecl || !CalleeDecl->getSubprogram())
745 continue;
746 CalleeSP = CalleeDecl->getSubprogram();
747 }
589748
590749 // TODO: Omit call site entries for runtime calls (objc_msgSend, etc).
591 // TODO: Add support for indirect calls.
592750
593751 bool IsTail = TII->isTailCall(MI);
594752
595 // For tail calls, no return PC information is needed. For regular calls,
596 // the return PC is needed to disambiguate paths in the call graph which
597 // could lead to some target function.
753 // For tail calls, for non-gdb tuning, no return PC information is needed.
754 // For regular calls (and tail calls in GDB tuning), the return PC
755 // is needed to disambiguate paths in the call graph which could lead to
756 // some target function.
598757 const MCExpr *PCOffset =
599 IsTail ? nullptr : getFunctionLocalOffsetAfterInsn(&MI);
600
601 assert((IsTail || PCOffset) && "Call without return PC information");
758 (IsTail && !tuneForGDB()) ? nullptr
759 : getFunctionLocalOffsetAfterInsn(&MI);
760
761 // Address of a call-like instruction for a normal call or a jump-like
762 // instruction for a tail call. This is needed for GDB + DWARF 4 tuning.
763 const MCSymbol *PCAddr =
764 ApplyGNUExtensions ? const_cast(getLabelAfterInsn(&MI))
765 : nullptr;
766
767 assert((IsTail || PCOffset || PCAddr) &&
768 "Call without return PC information");
769
602770 LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> "
603 << CalleeDecl->getName() << (IsTail ? " [tail]" : "")
604 << "\n");
605 CU.constructCallSiteEntryDIE(ScopeDIE, *CalleeDecl->getSubprogram(),
606 IsTail, PCOffset);
771 << (CalleeDecl ? CalleeDecl->getName()
772 : StringRef(MF.getSubtarget()
773 .getRegisterInfo()
774 ->getName(CallReg)))
775 << (IsTail ? " [IsTail]" : "") << "\n");
776
777 DIE &CallSiteDIE =
778 CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, IsTail, PCAddr,
779 PCOffset, CallReg);
780
781 // For now only GDB supports call site parameter debug info.
782 if (Asm->TM.Options.EnableDebugEntryValues &&
783 tuneForGDB()) {
784 ParamSet Params;
785 // Try to interpret values of call site parameters.
786 collectCallSiteParameters(&MI, Params);
787 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
788 }
607789 }
608790 }
609791 }
253253 }
254254 };
255255
256 /// Used for tracking debug info about call site parameters.
257 class DbgCallSiteParam {
258 private:
259 unsigned Register; ///< Parameter register at the callee entry point.
260 DbgValueLoc Value; ///< Corresponding location for the parameter value at
261 ///< the call site.
262 public:
263 DbgCallSiteParam(unsigned Reg, DbgValueLoc Val)
264 : Register(Reg), Value(Val) {
265 assert(Reg && "Parameter register cannot be undef");
266 }
267
268 unsigned getRegister() const { return Register; }
269 DbgValueLoc getValue() const { return Value; }
270 };
271
272 /// Collection used for storing debug call site parameters.
273 using ParamSet = SmallVector;
274
256275 /// Helper used to pair up a symbol and its DWARF compile unit.
257276 struct SymbolCU {
258277 SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {}
240240 return false;
241241 }
242242
243 // Handle simple register locations.
244 if (!isMemoryLocation() && !HasComplexExpression) {
243 // Handle simple register locations. If we are supposed to emit
244 // a call site parameter expression and if that expression is just a register
245 // location, emit it with addBReg and offset 0, because we should emit a DWARF
246 // expression representing a value, rather than a location.
247 if (!isMemoryLocation() && !HasComplexExpression && (!isParameterValue() ||
248 isEntryValue())) {
245249 for (auto &Reg : DwarfRegs) {
246250 if (Reg.DwarfRegNo >= 0)
247251 addReg(Reg.DwarfRegNo, Reg.Comment);
248252 addOpPiece(Reg.Size);
249253 }
250254
251 if (isEntryValue() && DwarfVersion >= 4)
255 if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4)
252256 emitOp(dwarf::DW_OP_stack_value);
253257
254258 DwarfRegs.clear();
339343
340344 while (ExprCursor) {
341345 auto Op = ExprCursor.take();
342 switch (Op->getOp()) {
346 uint64_t OpNum = Op->getOp();
347
348 if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
349 emitOp(OpNum);
350 continue;
351 } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
352 addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
353 continue;
354 }
355
356 switch (OpNum) {
343357 case dwarf::DW_OP_LLVM_fragment: {
344358 unsigned SizeInBits = Op->getArg(1);
345359 unsigned FragmentOffset = Op->getArg(0);
388402 case dwarf::DW_OP_lit0:
389403 case dwarf::DW_OP_not:
390404 case dwarf::DW_OP_dup:
391 emitOp(Op->getOp());
405 emitOp(OpNum);
392406 break;
393407 case dwarf::DW_OP_deref:
394408 assert(!isRegisterLocation());
457471 case dwarf::DW_OP_LLVM_tag_offset:
458472 TagOffset = Op->getArg(0);
459473 break;
474 case dwarf::DW_OP_regx:
475 emitOp(dwarf::DW_OP_regx);
476 emitUnsigned(Op->getArg(0));
477 break;
478 case dwarf::DW_OP_bregx:
479 emitOp(dwarf::DW_OP_bregx);
480 emitUnsigned(Op->getArg(0));
481 emitSigned(Op->getArg(1));
482 break;
460483 default:
461484 llvm_unreachable("unhandled opcode found in expression");
462485 }
463486 }
464487
465 if (isImplicitLocation())
488 if (isImplicitLocation() && !isParameterValue())
466489 // Turn this into an implicit location description.
467490 addStackValue();
468491 }
119119 enum { Unknown = 0, Register, Memory, Implicit };
120120
121121 /// The flags of location description being produced.
122 enum { EntryValue = 1 };
122 enum { EntryValue = 1, CallSiteParamValue };
123123
124124 unsigned LocationKind : 3;
125125 unsigned LocationFlags : 2;
144144
145145 bool isEntryValue() const {
146146 return LocationFlags & EntryValue;
147 }
148
149 bool isParameterValue() {
150 return LocationFlags & CallSiteParamValue;
147151 }
148152
149153 Optional TagOffset;
263267 LocationFlags |= EntryValue;
264268 }
265269
270 /// Lock this down to become a call site parameter location.
271 void setCallSiteParamValueFlag() {
272 LocationFlags |= CallSiteParamValue;
273 }
274
266275 /// Emit a machine register location. As an optimization this may also consume
267276 /// the prefix of a DwarfExpression if a more efficient representation for
268277 /// combining the register location and the first operation exists.
202202 return;
203203 }
204204 MDNodeToDieMap.insert(std::make_pair(Desc, D));
205 }
206
207 void DwarfUnit::insertDIE(DIE *D) {
208 MDNodeToDieMap.insert(std::make_pair(nullptr, D));
205209 }
206210
207211 void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) {
125125 /// type system, since DIEs for the type system can be shared across CUs and
126126 /// the mappings are kept in DwarfDebug.
127127 void insertDIE(const DINode *Desc, DIE *D);
128
129 void insertDIE(DIE *D);
128130
129131 /// Add a flag that is true to the DIE.
130132 void addFlag(DIE &Die, dwarf::Attribute Attribute);
2222 #include "llvm/CodeGen/TargetRegisterInfo.h"
2323 #include "llvm/CodeGen/TargetSchedule.h"
2424 #include "llvm/IR/DataLayout.h"
25 #include "llvm/IR/DebugInfoMetadata.h"
2526 #include "llvm/MC/MCAsmInfo.h"
2627 #include "llvm/MC/MCInstrItineraries.h"
2728 #include "llvm/Support/CommandLine.h"
11191120 return (DefCycle != -1 && DefCycle <= 1);
11201121 }
11211122
1123 Optional
1124 TargetInstrInfo::describeLoadedValue(const MachineInstr &MI) const {
1125 const MachineFunction *MF = MI.getMF();
1126 const MachineOperand *Op = nullptr;
1127 DIExpression *Expr = DIExpression::get(MF->getFunction().getContext(), {});;
1128 const MachineOperand *SrcRegOp, *DestRegOp;
1129
1130 if (isCopyInstr(MI, SrcRegOp, DestRegOp)) {
1131 Op = SrcRegOp;
1132 return ParamLoadedValue(Op, Expr);
1133 } else if (MI.isMoveImmediate()) {
1134 Op = &MI.getOperand(1);
1135 return ParamLoadedValue(Op, Expr);
1136 } else if (MI.hasOneMemOperand()) {
1137 int64_t Offset;
1138 const auto &TRI = MF->getSubtarget().getRegisterInfo();
1139 const auto &TII = MF->getSubtarget().getInstrInfo();
1140 const MachineOperand *BaseOp;
1141
1142 if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, TRI))
1143 return None;
1144
1145 Expr = DIExpression::prepend(Expr, DIExpression::DerefAfter, Offset);
1146 Op = BaseOp;
1147 return ParamLoadedValue(Op, Expr);
1148 }
1149
1150 return None;
1151 }
1152
11221153 /// Both DefMI and UseMI must be valid. By default, call directly to the
11231154 /// itinerary. This may be overriden by the target.
11241155 int TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
432432 return false;
433433 }
434434
435 bool TargetRegisterInfo::isCalleeSavedPhysReg(
436 unsigned PhysReg, const MachineFunction &MF) const {
437 if (PhysReg == 0)
438 return false;
439 const uint32_t *callerPreservedRegs =
440 getCallPreservedMask(MF, MF.getFunction().getCallingConv());
441 if (callerPreservedRegs) {
442 assert(isPhysicalRegister(PhysReg) && "Expected physical register");
443 return (callerPreservedRegs[PhysReg / 32] >> PhysReg % 32) & 1;
444 }
445 return false;
446 }
447
435448 bool TargetRegisterInfo::canRealignStack(const MachineFunction &MF) const {
436449 return !MF.getFunction().hasFnAttribute("no-realign-stack");
437450 }
732732 case DW_AT_call_data_value:
733733 // Extensions.
734734 case DW_AT_GNU_call_site_value:
735 case DW_AT_GNU_call_site_target:
735736 return true;
736737 default:
737738 return false;
827827 }
828828
829829 unsigned DIExpression::ExprOperand::getSize() const {
830 switch (getOp()) {
830 uint64_t Op = getOp();
831
832 if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)
833 return 2;
834
835 switch (Op) {
831836 case dwarf::DW_OP_LLVM_convert:
832837 case dwarf::DW_OP_LLVM_fragment:
838 case dwarf::DW_OP_bregx:
833839 return 3;
834840 case dwarf::DW_OP_constu:
841 case dwarf::DW_OP_consts:
835842 case dwarf::DW_OP_deref_size:
836843 case dwarf::DW_OP_plus_uconst:
837844 case dwarf::DW_OP_LLVM_tag_offset:
838845 case dwarf::DW_OP_entry_value:
846 case dwarf::DW_OP_regx:
839847 return 2;
840848 default:
841849 return 1;
848856 if (I->get() + I->getSize() > E->get())
849857 return false;
850858
859 uint64_t Op = I->getOp();
860 if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||
861 (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31))
862 return true;
863
851864 // Check that the operand is valid.
852 switch (I->getOp()) {
865 switch (Op) {
853866 default:
854867 return false;
855868 case dwarf::DW_OP_LLVM_fragment:
904917 case dwarf::DW_OP_lit0:
905918 case dwarf::DW_OP_not:
906919 case dwarf::DW_OP_dup:
920 case dwarf::DW_OP_regx:
921 case dwarf::DW_OP_bregx:
907922 break;
908923 }
909924 }
2929 #include "llvm/CodeGen/StackMaps.h"
3030 #include "llvm/IR/DerivedTypes.h"
3131 #include "llvm/IR/Function.h"
32 #include "llvm/IR/LLVMContext.h"
32 #include "llvm/IR/DebugInfoMetadata.h"
3333 #include "llvm/MC/MCAsmInfo.h"
3434 #include "llvm/MC/MCExpr.h"
3535 #include "llvm/MC/MCInst.h"
73667366 }
73677367 }
73687368
7369 Optional
7370 X86InstrInfo::describeLoadedValue(const MachineInstr &MI) const {
7371 const MachineOperand *Op = nullptr;
7372 DIExpression *Expr = nullptr;
7373
7374 switch (MI.getOpcode()) {
7375 case X86::LEA32r:
7376 case X86::LEA64r:
7377 case X86::LEA64_32r: {
7378 // Operand 4 could be global address. For now we do not support
7379 // such situation.
7380 if (!MI.getOperand(4).isImm() || !MI.getOperand(2).isImm())
7381 return None;
7382
7383 const MachineOperand &Op1 = MI.getOperand(1);
7384 const MachineOperand &Op2 = MI.getOperand(3);
7385 const TargetRegisterInfo *TRI = &getRegisterInfo();
7386 assert(Op2.isReg() &&
7387 (Op2.getReg() == X86::NoRegister ||
7388 TargetRegisterInfo::isPhysicalRegister(Op2.getReg())));
7389
7390 // Omit situations like:
7391 // %rsi = lea %rsi, 4, ...
7392 if ((Op1.isReg() && Op1.getReg() == MI.getOperand(0).getReg()) ||
7393 Op2.getReg() == MI.getOperand(0).getReg())
7394 return None;
7395 else if ((Op1.isReg() && Op1.getReg() != X86::NoRegister &&
7396 TRI->regsOverlap(Op1.getReg(), MI.getOperand(0).getReg())) ||
7397 (Op2.getReg() != X86::NoRegister &&
7398 TRI->regsOverlap(Op2.getReg(), MI.getOperand(0).getReg())))
7399 return None;
7400
7401 int64_t Coef = MI.getOperand(2).getImm();
7402 int64_t Offset = MI.getOperand(4).getImm();
7403 SmallVector Ops;
7404
7405 if ((Op1.isReg() && Op1.getReg() != X86::NoRegister)) {
7406 Op = &Op1;
7407 } else if (Op1.isFI())
7408 Op = &Op1;
7409
7410 if (Op && Op->isReg() && Op->getReg() == Op2.getReg() && Coef > 0) {
7411 Ops.push_back(dwarf::DW_OP_constu);
7412 Ops.push_back(Coef + 1);
7413 Ops.push_back(dwarf::DW_OP_mul);
7414 } else {
7415 if (Op && Op2.getReg() != X86::NoRegister) {
7416 int dwarfReg = TRI->getDwarfRegNum(Op2.getReg(), false);
7417 if (dwarfReg < 0)
7418 return None;
7419 else if (dwarfReg < 32) {
7420 Ops.push_back(dwarf::DW_OP_breg0 + dwarfReg);
7421 Ops.push_back(0);
7422 } else {
7423 Ops.push_back(dwarf::DW_OP_bregx);
7424 Ops.push_back(dwarfReg);
7425 Ops.push_back(0);
7426 }
7427 } else if (!Op) {
7428 assert(Op2.getReg() != X86::NoRegister);
7429 Op = &Op2;
7430 }
7431
7432 if (Coef > 1) {
7433 assert(Op2.getReg() != X86::NoRegister);
7434 Ops.push_back(dwarf::DW_OP_constu);
7435 Ops.push_back(Coef);
7436 Ops.push_back(dwarf::DW_OP_mul);
7437 }
7438
7439 if (((Op1.isReg() && Op1.getReg() != X86::NoRegister) || Op1.isFI()) &&
7440 Op2.getReg() != X86::NoRegister) {
7441 Ops.push_back(dwarf::DW_OP_plus);
7442 }
7443 }
7444
7445 DIExpression::appendOffset(Ops, Offset);
7446 Expr = DIExpression::get(MI.getMF()->getFunction().getContext(), Ops);
7447
7448 return ParamLoadedValue(Op, Expr);;
7449 }
7450 default:
7451 return TargetInstrInfo::describeLoadedValue(MI);
7452 }
7453 }
7454
73697455 /// This is an architecture-specific helper function of reassociateOps.
73707456 /// Set special operand attributes for new instructions after reassociation.
73717457 void X86InstrInfo::setSpecialOperandAttr(MachineInstr &OldMI1,
526526 #define GET_INSTRINFO_HELPER_DECLS
527527 #include "X86GenInstrInfo.inc"
528528
529 Optional
530 describeLoadedValue(const MachineInstr &MI) const override;
531
529532 protected:
530533 /// Commutes the operands in the given instruction by changing the operands
531534 /// order and/or changing the instruction's opcode and/or the immediate value
0 # RUN: llc -debug-entry-values -start-after=machineverifier -filetype=obj %s -o -| llvm-dwarfdump -| FileCheck %s
1 #
2 # CHECK: DW_TAG_GNU_call_site
3 # CHECK-NEXT: DW_AT_abstract_origin {{.*}} "foo"
4 # CHECK-NEXT: DW_AT_low_pc
5 # CHECK-EMPTY:
6 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
7 # CHECK-NEXT: DW_AT_location (DW_OP_reg2 RCX)
8 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+0)
9 # CHECK-EMPTY:
10 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
11 # CHECK-NEXT: DW_AT_location (DW_OP_reg1 RDX)
12 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +8)
13 # CHECK-EMPTY:
14 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
15 # CHECK-NEXT: DW_AT_location (DW_OP_reg5 RDI)
16 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_GNU_entry_value(DW_OP_reg4 RSI))
17 # CHECK-EMPTY:
18 # CHECK: DW_TAG_GNU_call_site
19 # CHECK-NEXT: DW_AT_abstract_origin {{.*}}"foo"
20 # CHECK-NEXT: DW_AT_low_pc
21 # CHECK-EMPTY:
22 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
23 # CHECK-NEXT: DW_AT_location (DW_OP_reg2 RCX)
24 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +8, DW_OP_deref)
25 # CHECK-EMPTY:
26 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
27 # CHECK-NEXT: DW_AT_location (DW_OP_reg4 RSI)
28 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit4)
29 # CHECK-EMPTY:
30 # CHECK-NOT: DW_TAG_GNU_call_site_parameter
31 #
32 # Check that call site interpretation analysis can interpret instructions such
33 # as move immediate, register to register moves, stack loading and LEA
34 # instructions. Last negative check should verify that we are not producing
35 # interpretation for RDX register since its loaded value is call clobberable.
36 # Also check that we are generating proper call site debug entities.
37 --- |
38 ; ModuleID = 'dbgcall-site-interpretation.c'
39 source_filename = "dbgcall-site-interpretation.c"
40 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
41 target triple = "x86_64-unknown-linux-gnu"
42
43 ; Function Attrs: nounwind uwtable
44 define dso_local i32 @baa(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) local_unnamed_addr !dbg !9 {
45 entry:
46 %arg3.addr = alloca i32, align 4
47 %local2 = alloca i32, align 4
48 call void @llvm.dbg.value(metadata i32 %arg1, metadata !14, metadata !DIExpression()), !dbg !21
49 call void @llvm.dbg.value(metadata i32 %arg2, metadata !15, metadata !DIExpression()), !dbg !21
50 call void @llvm.dbg.value(metadata i32 %arg3, metadata !16, metadata !DIExpression()), !dbg !21
51 store i32 %arg3, i32* %arg3.addr, align 4
52 call void @llvm.dbg.value(metadata i32 %arg4, metadata !17, metadata !DIExpression()), !dbg !21
53 %0 = bitcast i32* %local2 to i8*, !dbg !21
54 call void @llvm.dbg.value(metadata i32* %arg3.addr, metadata !16, metadata !DIExpression(DW_OP_deref)), !dbg !21
55 %call = call i32 @foo(i32 %arg1, i32 %arg2, i32* nonnull %arg3.addr, i32 %arg4), !dbg !21
56 call void @llvm.dbg.value(metadata i32 %call, metadata !18, metadata !DIExpression()), !dbg !21
57 %cmp = icmp sgt i32 %arg1, %arg2, !dbg !21
58 %1 = load i32, i32* %arg3.addr, align 4, !dbg !21
59 call void @llvm.dbg.value(metadata i32 %1, metadata !16, metadata !DIExpression()), !dbg !21
60 %add = add nsw i32 %1, %arg1, !dbg !21
61 %add1 = add nsw i32 %arg4, %arg2, !dbg !21
62 %local1.0 = select i1 %cmp, i32 %add, i32 %add1, !dbg !21
63 call void @llvm.dbg.value(metadata i32 %local1.0, metadata !18, metadata !DIExpression()), !dbg !21
64 %rem = srem i32 %1, %arg1, !dbg !21
65 %tobool = icmp eq i32 %rem, 0, !dbg !21
66 %mul = mul nsw i32 %1, %arg1, !dbg !21
67 %add3 = add nsw i32 %1, %arg4, !dbg !21
68 %storemerge = select i1 %tobool, i32 %mul, i32 %add3, !dbg !21
69 call void @llvm.dbg.value(metadata i32 %storemerge, metadata !19, metadata !DIExpression()), !dbg !21
70 store i32 %storemerge, i32* %local2, align 4, !dbg !21
71 %cmp6 = icmp slt i32 %storemerge, %arg4, !dbg !21
72 %local3.0.v = select i1 %cmp6, i32 %local1.0, i32 %arg1, !dbg !21
73 %local3.0 = mul nsw i32 %local3.0.v, %storemerge, !dbg !21
74 call void @llvm.dbg.value(metadata i32 %local3.0, metadata !20, metadata !DIExpression()), !dbg !21
75 call void @llvm.dbg.value(metadata i32* %local2, metadata !19, metadata !DIExpression(DW_OP_deref)), !dbg !21
76 %call12 = call i32 @foo(i32 %local1.0, i32 4, i32* nonnull %local2, i32 %local3.0), !dbg !21
77 call void @llvm.dbg.value(metadata i32 %call12, metadata !14, metadata !DIExpression()), !dbg !21
78 %add13 = add nsw i32 %call12, 4, !dbg !21
79 ret i32 %add13, !dbg !21
80 }
81
82 declare !dbg !4 dso_local i32 @foo(i32, i32, i32*, i32) local_unnamed_addr
83
84 ; Function Attrs: nounwind readnone speculatable
85 declare void @llvm.dbg.value(metadata, metadata, metadata)
86
87 !llvm.dbg.cu = !{!0}
88 !llvm.module.flags = !{!5, !6, !7}
89 !llvm.ident = !{!8}
90
91 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None)
92 !1 = !DIFile(filename: "dbgcall-site-interpretation.c", directory: "/dir")
93 !2 = !{}
94 !3 = !{!4}
95 !4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 9, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
96 !5 = !{i32 2, !"Dwarf Version", i32 4}
97 !6 = !{i32 2, !"Debug Info Version", i32 3}
98 !7 = !{i32 1, !"wchar_size", i32 4}
99 !8 = !{!"clang version 9.0.0"}
100 !9 = distinct !DISubprogram(name: "baa", scope: !1, file: !1, line: 10, type: !10, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13)
101 !10 = !DISubroutineType(types: !11)
102 !11 = !{!12, !12, !12, !12, !12}
103 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
104 !13 = !{!14, !15, !16, !17, !18, !19, !20}
105 !14 = !DILocalVariable(name: "arg1", arg: 1, scope: !9, file: !1, line: 10, type: !12)
106 !15 = !DILocalVariable(name: "arg2", arg: 2, scope: !9, file: !1, line: 10, type: !12, flags: DIFlagArgumentNotModified)
107 !16 = !DILocalVariable(name: "arg3", arg: 3, scope: !9, file: !1, line: 10, type: !12)
108 !17 = !DILocalVariable(name: "arg4", arg: 4, scope: !9, file: !1, line: 10, type: !12, flags: DIFlagArgumentNotModified)
109 !18 = !DILocalVariable(name: "local1", scope: !9, file: !1, line: 11, type: !12)
110 !19 = !DILocalVariable(name: "local2", scope: !9, file: !1, line: 11, type: !12)
111 !20 = !DILocalVariable(name: "local3", scope: !9, file: !1, line: 11, type: !12)
112 !21 = !DILocation(line: 10, column: 13, scope: !9)
113
114 ...
115 ---
116 name: baa
117 liveins:
118 - { reg: '$edi', virtual-reg: '' }
119 - { reg: '$esi', virtual-reg: '' }
120 - { reg: '$edx', virtual-reg: '' }
121 - { reg: '$ecx', virtual-reg: '' }
122 callSites:
123 - { bb: 0, offset: 23, fwdArgRegs:
124 - { arg: 0, reg: '$edi' }
125 - { arg: 1, reg: '$esi' }
126 - { arg: 2, reg: '$rdx' }
127 - { arg: 3, reg: '$ecx' } }
128 - { bb: 0, offset: 49, fwdArgRegs:
129 - { arg: 0, reg: '$edi' }
130 - { arg: 1, reg: '$esi' }
131 - { arg: 2, reg: '$rdx' }
132 - { arg: 3, reg: '$ecx' } }
133 body: |
134 bb.0.entry:
135 liveins: $ecx, $edi, $edx, $esi, $r15, $r14, $rbx
136
137 DBG_VALUE $edi, $noreg, !14, !DIExpression(), debug-location !21
138 DBG_VALUE $esi, $noreg, !15, !DIExpression(), debug-location !21
139 DBG_VALUE $edx, $noreg, !16, !DIExpression(), debug-location !21
140 DBG_VALUE $ecx, $noreg, !17, !DIExpression(), debug-location !21
141 frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
142 CFI_INSTRUCTION def_cfa_offset 16
143 frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
144 CFI_INSTRUCTION def_cfa_offset 24
145 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
146 CFI_INSTRUCTION def_cfa_offset 32
147 $rsp = frame-setup SUB64ri8 $rsp, 16, implicit-def dead $eflags
148 CFI_INSTRUCTION def_cfa_offset 48
149 CFI_INSTRUCTION offset $rbx, -32
150 CFI_INSTRUCTION offset $r14, -24
151 CFI_INSTRUCTION offset $r15, -16
152 $r14d = MOV32rr $ecx, implicit-def $r14
153 DBG_VALUE $edx, $noreg, !16, !DIExpression(), debug-location !21
154 $r15d = MOV32rr $esi, implicit-def $r15
155 $ebx = MOV32rr $edi, implicit-def $rbx
156 $edi = MOV32rr $esi
157 MOV32mr $rsp, 1, $noreg, 8, $noreg, killed renamable $edx :: (store 4 into %ir.arg3.addr)
158 renamable $rdx = LEA64r $rsp, 1, $noreg, 8, $noreg
159 renamable $ecx = MOV32rr $r14d,
160 CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit $rdx, implicit $ecx, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, implicit-def $rax, debug-location !21
161 DBG_VALUE $noreg, $noreg, !18, !DIExpression(), debug-location !21
162 $rdx = MOV64rr renamable $rax
163 $ecx = KILL renamable $ecx, implicit-def $rcx
164 renamable $eax = LEA64_32r renamable $rcx, 1, renamable $rbx, 0, $noreg, debug-location !21
165 renamable $edi = LEA64_32r renamable $r14, 1, renamable $r15, 0, $noreg, debug-location !21
166 CMP32rr renamable $ebx, renamable $r15d, implicit-def $eflags, implicit killed $r15, debug-location !21
167 renamable $edi = CMOV32rr killed renamable $edi, killed renamable $eax, 15, implicit killed $eflags, debug-location !21
168 DBG_VALUE $edi, $noreg, !18, !DIExpression(), debug-location !21
169 $eax = MOV32rr $ecx, debug-location !21
170 CDQ implicit-def $eax, implicit-def $edx, implicit $eax, debug-location !21
171 IDIV32r renamable $ebx, implicit-def dead $eax, implicit-def $edx, implicit-def dead $eflags, implicit $eax, implicit $edx, debug-location !21
172 $eax = MOV32rr $ecx, debug-location !21
173 renamable $eax = nsw IMUL32rr killed renamable $eax, renamable $ebx, implicit-def dead $eflags, debug-location !21
174 renamable $ecx = nsw ADD32rr renamable $ecx, renamable $r14d, implicit-def dead $eflags, implicit killed $rcx, implicit-def $rcx, debug-location !21
175 TEST32rr killed renamable $edx, renamable $edx, implicit-def $eflags, debug-location !21
176 renamable $ecx = CMOV32rr renamable $ecx, killed renamable $eax, 4, implicit killed $eflags, implicit killed $rcx, implicit-def $rcx, debug-location !21
177 DBG_VALUE $ecx, $noreg, !19, !DIExpression(), debug-location !21
178 MOV32mr $rsp, 1, $noreg, 12, $noreg, renamable $ecx, debug-location !21 :: (store 4 into %ir.local2)
179 CMP32rr renamable $ecx, renamable $r14d, implicit-def $eflags, implicit killed $r14, debug-location !21
180 renamable $ebx = CMOV32rr renamable $ebx, renamable $edi, 12, implicit killed $eflags, implicit killed $rbx, implicit-def $rbx, debug-location !21
181 renamable $ecx = nsw IMUL32rr renamable $ecx, renamable $ebx, implicit-def dead $eflags, implicit killed $rbx, implicit killed $rcx, implicit-def $rcx, debug-location !21
182 DBG_VALUE $rsp, $noreg, !19, !DIExpression(DW_OP_plus_uconst, 12, DW_OP_deref), debug-location !21
183 DBG_VALUE $ecx, $noreg, !20, !DIExpression(), debug-location !21
184 $esi = MOV32ri 4, debug-location !21
185 renamable $ecx = MOV32rm $rsp, 1, $noreg, 8, $noreg, implicit-def $rcx, debug-location !21 :: (dereferenceable load 4 from %ir.arg3.addr)
186 CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit $rdx, implicit $ecx, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, implicit-def $rax, debug-location !21
187 DBG_VALUE $eax, $noreg, !14, !DIExpression(), debug-location !21
188 renamable $eax = nsw ADD32ri8 killed renamable $eax, 4, implicit-def dead $eflags, debug-location !21
189 $rsp = frame-destroy ADD64ri8 $rsp, 16, implicit-def dead $eflags, debug-location !21
190 CFI_INSTRUCTION def_cfa_offset 32, debug-location !21
191 $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !21
192 CFI_INSTRUCTION def_cfa_offset 24, debug-location !21
193 $r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !21
194 DBG_VALUE $ecx, $noreg, !17, !DIExpression(DW_OP_entry_value, 1), debug-location !21
195 CFI_INSTRUCTION def_cfa_offset 16, debug-location !21
196 $r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !21
197 DBG_VALUE $esi, $noreg, !15, !DIExpression(DW_OP_entry_value, 1), debug-location !21
198 CFI_INSTRUCTION def_cfa_offset 8, debug-location !21
199 RETQ $eax, debug-location !21
200
201 ...
0 # RUN: llc -debug-entry-values -start-after=machineverifier -filetype=obj %s -o -| llvm-dwarfdump -| FileCheck %s
1 # CHECK: DW_TAG_GNU_call_site
2 # CHECK-NEXT: DW_AT_abstract_origin {{.*}} "foo")
3 # CHECK-NEXT: DW_AT_low_pc {{.*}}
4 # CHECK-EMPTY:
5 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
6 # CHECK-NEXT: DW_AT_location (DW_OP_reg9 R9)
7 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg15 R15+10)
8 # CHECK-EMPTY:
9 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
10 # CHECK-NEXT: DW_AT_location (DW_OP_reg8 R8)
11 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg15 R15+0, DW_OP_lit2, DW_OP_mul, DW_OP_plus_uconst 0x8)
12 # CHECK-EMPTY:
13 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
14 # CHECK-NEXT: DW_AT_location (DW_OP_reg1 RDX)
15 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+0, DW_OP_lit5, DW_OP_mul, DW_OP_plus_uconst 0x8)
16 # CHECK-EMPTY:
17 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
18 # CHECK-NEXT: DW_AT_location (DW_OP_reg4 RSI)
19 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+0)
20 # CHECK-EMPTY:
21 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
22 # CHECK-NEXT: DW_AT_location (DW_OP_reg5 RDI)
23 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+0, DW_OP_breg15 R15+0, DW_OP_lit2, DW_OP_mul, DW_OP_plus, DW_OP_plus_uconst 0x4)
24 # CHECK-EMPTY:
25 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
26 # CHECK-NEXT: DW_AT_location (DW_OP_reg2 RCX)
27 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+0, DW_OP_breg15 R15+0, DW_OP_plus)
28 # CHECK: DW_TAG_GNU_call_site
29 # CHECK-NEXT: DW_AT_abstract_origin {{.*}} "foo2")
30 # CHECK-NEXT: DW_AT_low_pc {{.*}}
31 # CHECK-EMPTY:
32 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
33 # CHECK-NEXT: DW_AT_location (DW_OP_reg5 RDI)
34 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+0, DW_OP_lit2, DW_OP_mul)
35 --- |
36 ; ModuleID = 'dbgcall-site-lea-interpretation.ll'
37 source_filename = "dbgcall-site-lea-interpretation.c"
38 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
39 target triple = "x86_64-unknown-linux-gnu"
40
41 define dso_local i32 @baa(i32 %arg1, i32 %arg2, i32 %arg3) local_unnamed_addr !dbg !10 {
42 entry:
43 %arg1.addr = alloca i32, align 4
44 %arg3.addr = alloca i32, align 4
45 %local1 = alloca i32, align 4
46 store i32 %arg1, i32* %arg1.addr, align 4
47 store i32 %arg3, i32* %arg3.addr, align 4
48 %0 = bitcast i32* %local1 to i8*, !dbg !14
49 %mul = mul nsw i32 %arg3, %arg1, !dbg !14
50 store i32 %mul, i32* %local1, align 4, !dbg !14
51 %add = add nsw i32 %arg2, %arg1, !dbg !14
52 %sub = sub nsw i32 %add, %arg3, !dbg !14
53 %call = call i32 @foo(i32 %mul, i32 %sub, i32* nonnull %local1, i32* nonnull %arg1.addr, i32* nonnull %arg3.addr, i32 %add), !dbg !14
54 %1 = load i32, i32* %local1, align 4, !dbg !14
55 %add2 = add nsw i32 %1, %call, !dbg !14
56 store i32 %add2, i32* %local1, align 4, !dbg !14
57 %call3 = call i32 @foo2(i32* nonnull %local1), !dbg !14
58 %2 = load i32, i32* %local1, align 4, !dbg !14
59 ret i32 %2, !dbg !14
60 }
61
62 declare !dbg !4 dso_local i32 @foo(i32, i32, i32*, i32*, i32*, i32) local_unnamed_addr
63
64 declare !dbg !5 dso_local i32 @foo2(i32*) local_unnamed_addr
65
66 !llvm.dbg.cu = !{!0}
67 !llvm.module.flags = !{!6, !7, !8}
68 !llvm.ident = !{!9}
69
70 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None)
71 !1 = !DIFile(filename: "dbgcall-site-lea-interpretation.c", directory: "/dir")
72 !2 = !{}
73 !3 = !{!4, !5}
74 !4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
75 !5 = !DISubprogram(name: "foo2", scope: !1, file: !1, line: 9, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
76 !6 = !{i32 2, !"Dwarf Version", i32 4}
77 !7 = !{i32 2, !"Debug Info Version", i32 3}
78 !8 = !{i32 1, !"wchar_size", i32 4}
79 !9 = !{!"clang version 9.0.0"}
80 !10 = distinct !DISubprogram(name: "baa", scope: !1, file: !1, line: 11, type: !11, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
81 !11 = !DISubroutineType(types: !12)
82 !12 = !{!13, !13, !13, !13}
83 !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
84 !14 = !DILocation(line: 11, column: 13, scope: !10)
85
86 ...
87 ---
88 name: baa
89 liveins:
90 - { reg: '$edi', virtual-reg: '' }
91 - { reg: '$esi', virtual-reg: '' }
92 - { reg: '$edx', virtual-reg: '' }
93 callSites:
94 - { bb: 0, offset: 21, fwdArgRegs:
95 - { arg: 0, reg: '$edi' }
96 - { arg: 1, reg: '$esi' }
97 - { arg: 2, reg: '$rdx' }
98 - { arg: 3, reg: '$rcx' }
99 - { arg: 4, reg: '$r8' }
100 - { arg: 5, reg: '$r9d' } }
101 - { bb: 0, offset: 24, fwdArgRegs:
102 - { arg: 0, reg: '$rdi' } }
103 body: |
104 bb.0.entry:
105 liveins: $edi, $edx, $esi, $rbx
106
107 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
108 CFI_INSTRUCTION def_cfa_offset 16
109 $rsp = frame-setup SUB64ri8 $rsp, 16, implicit-def dead $eflags
110 CFI_INSTRUCTION def_cfa_offset 32
111 CFI_INSTRUCTION offset $rbx, -16
112 $r9d = MOV32rr $esi
113 $r14 = MOV64rr $rsi
114 $r15 = MOV64rr $rdi
115 MOV32mr $rsp, 1, $noreg, 12, $noreg, renamable $edi :: (store 4 into %ir.arg1.addr)
116 MOV32mr $rsp, 1, $noreg, 8, $noreg, renamable $edx :: (store 4 into %ir.arg3.addr)
117 renamable $r9d = nsw ADD32rr killed renamable $r9d, renamable $edi, implicit-def dead $eflags, debug-location !14
118 $esi = MOV32rr $r9d, debug-location !14
119 renamable $esi = nsw SUB32rr killed renamable $esi, renamable $edx, implicit-def dead $eflags, debug-location !14
120 renamable $edx = nsw IMUL32rr killed renamable $edx, killed renamable $edi, implicit-def dead $eflags, debug-location !14
121 MOV32mr $rsp, 1, $noreg, 4, $noreg, renamable $edx, debug-location !14 :: (store 4 into %ir.local1)
122 renamable $rcx = LEA64r $r14, 1, $r15, 0, $noreg
123 renamable $rdi = LEA64r $r14, 2, $r15, 4, $noreg
124 renamable $rsi = LEA64r $r14, 1, $noreg, 0, $noreg
125 renamable $rdx = LEA64r $r14, 4, $r14, 8, $noreg
126 renamable $r8 = LEA64r $noreg, 2, $r15, 8, $noreg
127 renamable $r9 = LEA64r $noreg, 1, $r15, 10, $noreg, implicit-def $r9d
128 CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit $rdx, implicit $rcx, implicit $r8, implicit $r9d, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !14
129 ADD32mr $rsp, 1, $noreg, 4, $noreg, killed renamable $eax, implicit-def dead $eflags, debug-location !14 :: (store 4 into %ir.local1), (dereferenceable load 4 from %ir.local1)
130 $rdi = LEA64r $r14, 1, killed $r14, 0, $noreg
131 CALL64pcrel32 @foo2, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def dead $eax, debug-location !14
132 renamable $eax = MOV32rm $rsp, 1, $noreg, 4, $noreg, debug-location !14 :: (dereferenceable load 4 from %ir.local1)
133 $rsp = frame-destroy ADD64ri8 $rsp, 16, implicit-def dead $eflags, debug-location !14
134 CFI_INSTRUCTION def_cfa_offset 16, debug-location !14
135 $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !14
136 CFI_INSTRUCTION def_cfa_offset 8, debug-location !14
137 RETQ $eax, debug-location !14
138
139 ...
0 # RUN: llc -debug-entry-values -filetype=obj -mtriple=x86_64-unknown-unknown -start-after=machineverifier -o - %s| llvm-dwarfdump - | FileCheck %s
1 #
2 # extern void foo(int *a, int b, int c, int d, int e, int f);
3 # extern int getVal();
4 #
5 # void baa(int arg1, int arg2, int arg3) {
6 # int local1 = getVal();
7 # foo(&local1, arg2, 10, 15, arg3 + 3, arg1 + arg2);
8 # }
9 #
10 # CHECK: DW_TAG_GNU_call_site
11 # CHECK: DW_AT_abstract_origin {{.*}} "getVal"
12 #
13 # CHECK: DW_TAG_GNU_call_site
14 # CHECK: DW_AT_abstract_origin {{.*}} "foo"
15 # CHECK: DW_AT_low_pc {{.*}}
16 # CHECK-EMPTY:
17 # CHECK: DW_TAG_GNU_call_site_parameter
18 # CHECK-NEXT: DW_AT_location (DW_OP_reg2 RCX)
19 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit15)
20 # CHECK: DW_TAG_GNU_call_site_parameter
21 # CHECK-NEXT: DW_AT_location (DW_OP_reg1 RDX)
22 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit10)
23 # CHECK: DW_TAG_GNU_call_site_parameter
24 # CHECK-NEXT: DW_AT_location (DW_OP_reg4 RSI)
25 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg3 RBX+0)
26 # CHECK: DW_TAG_GNU_call_site_parameter
27 # CHECK-NEXT: DW_AT_location (DW_OP_reg5 RDI)
28 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +12)
29 # CHECK: DW_TAG_GNU_call_site_parameter
30 # CHECK-NEXT: DW_AT_location (DW_OP_reg9 R9)
31 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg15 R15+0, DW_OP_breg3 RBX+0, DW_OP_plus)
32 # CHECK: DW_TAG_GNU_call_site_parameter
33 # CHECK-NEXT: DW_AT_location (DW_OP_reg8 R8)
34 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+3)
35 --- |
36 ; ModuleID = 'test.c'
37 source_filename = "test.c"
38 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
39 target triple = "x86_64-unknown-linux-gnu"
40
41 ; Function Attrs: nounwind uwtable
42 define dso_local void @baa(i32 %arg1, i32 %arg2, i32 %arg3) local_unnamed_addr !dbg !10 {
43 entry:
44 %local1 = alloca i32, align 4
45 call void @llvm.dbg.value(metadata i32 %arg1, metadata !15, metadata !DIExpression()), !dbg !19
46 call void @llvm.dbg.value(metadata i32 %arg2, metadata !16, metadata !DIExpression()), !dbg !20
47 call void @llvm.dbg.value(metadata i32 %arg3, metadata !17, metadata !DIExpression()), !dbg !21
48 %0 = bitcast i32* %local1 to i8*, !dbg !22
49 %call = tail call i32 (...) @getVal(), !dbg !23
50 call void @llvm.dbg.value(metadata i32 %call, metadata !18, metadata !DIExpression()), !dbg !24
51 store i32 %call, i32* %local1, align 4, !dbg !24
52 %add = add nsw i32 %arg3, 3, !dbg !24
53 %add1 = add nsw i32 %arg2, %arg1, !dbg !24
54 call void @llvm.dbg.value(metadata i32* %local1, metadata !18, metadata !DIExpression(DW_OP_deref)), !dbg !24
55 call void @foo(i32* nonnull %local1, i32 %arg2, i32 10, i32 15, i32 %add, i32 %add1), !dbg !24
56 ret void, !dbg !24
57 }
58
59 declare !dbg !4 dso_local i32 @getVal(...) local_unnamed_addr
60
61 declare !dbg !5 dso_local void @foo(i32*, i32, i32, i32, i32, i32) local_unnamed_addr
62
63 ; Function Attrs: nounwind readnone speculatable
64 declare void @llvm.dbg.value(metadata, metadata, metadata)
65
66 !llvm.dbg.cu = !{!0}
67 !llvm.module.flags = !{!6, !7, !8}
68 !llvm.ident = !{!9}
69
70 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None)
71 !1 = !DIFile(filename: "test.c", directory: "/dir")
72 !2 = !{}
73 !3 = !{!4, !5}
74 !4 = !DISubprogram(name: "getVal", scope: !1, file: !1, line: 2, spFlags: DISPFlagOptimized, retainedNodes: !2)
75 !5 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
76 !6 = !{i32 2, !"Dwarf Version", i32 4}
77 !7 = !{i32 2, !"Debug Info Version", i32 3}
78 !8 = !{i32 1, !"wchar_size", i32 4}
79 !9 = !{!"clang version 9.0.0"}
80 !10 = distinct !DISubprogram(name: "baa", scope: !1, file: !1, line: 4, type: !11, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !14)
81 !11 = !DISubroutineType(types: !12)
82 !12 = !{null, !13, !13, !13}
83 !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
84 !14 = !{!15, !16, !17, !18}
85 !15 = !DILocalVariable(name: "arg1", arg: 1, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
86 !16 = !DILocalVariable(name: "arg2", arg: 2, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
87 !17 = !DILocalVariable(name: "arg3", arg: 3, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
88 !18 = !DILocalVariable(name: "local1", scope: !10, file: !1, line: 5, type: !13)
89 !19 = !DILocation(line: 4, column: 14, scope: !10)
90 !20 = !DILocation(line: 4, column: 24, scope: !10)
91 !21 = !DILocation(line: 4, column: 34, scope: !10)
92 !22 = !DILocation(line: 5, column: 3, scope: !10)
93 !23 = !DILocation(line: 5, column: 16, scope: !10)
94 !24 = !DILocation(line: 5, column: 7, scope: !10)
95
96 ...
97 ---
98 name: baa
99 liveins:
100 - { reg: '$edi', virtual-reg: '' }
101 - { reg: '$esi', virtual-reg: '' }
102 - { reg: '$edx', virtual-reg: '' }
103 callSites:
104 - { bb: 0, offset: 21, fwdArgRegs: [] }
105 - { bb: 0, offset: 31, fwdArgRegs:
106 - { arg: 0, reg: '$rdi' }
107 - { arg: 1, reg: '$esi' }
108 - { arg: 2, reg: '$edx' }
109 - { arg: 3, reg: '$ecx' }
110 - { arg: 4, reg: '$r8d' }
111 - { arg: 5, reg: '$r9d' } }
112 body: |
113 bb.0.entry:
114 liveins: $edi, $edx, $esi, $r15, $r14, $rbx
115
116 DBG_VALUE $edi, $noreg, !15, !DIExpression(), debug-location !19
117 DBG_VALUE $esi, $noreg, !16, !DIExpression(), debug-location !20
118 DBG_VALUE $edx, $noreg, !17, !DIExpression(), debug-location !21
119 frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
120 CFI_INSTRUCTION def_cfa_offset 16
121 frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
122 CFI_INSTRUCTION def_cfa_offset 24
123 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
124 CFI_INSTRUCTION def_cfa_offset 32
125 $rsp = frame-setup SUB64ri8 $rsp, 16, implicit-def dead $eflags
126 CFI_INSTRUCTION def_cfa_offset 48
127 CFI_INSTRUCTION offset $rbx, -32
128 CFI_INSTRUCTION offset $r14, -24
129 CFI_INSTRUCTION offset $r15, -16
130 $r14d = MOV32rr $edx, implicit-def $r14
131 $ebx = MOV32rr $esi, implicit-def $rbx
132 $r15d = MOV32rr $edi, implicit-def $r15
133 DBG_VALUE $r14d, $noreg, !17, !DIExpression(), debug-location !21
134 DBG_VALUE $ebx, $noreg, !16, !DIExpression(), debug-location !20
135 DBG_VALUE $r15d, $noreg, !15, !DIExpression(), debug-location !19
136 dead $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, implicit-def $al, debug-location !23
137 CALL64pcrel32 @getVal, csr_64, implicit $rsp, implicit $ssp, implicit $al, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !23
138 DBG_VALUE $eax, $noreg, !18, !DIExpression(), debug-location !24
139 MOV32mr $rsp, 1, $noreg, 12, $noreg, killed renamable $eax, debug-location !24 :: (store 4 into %ir.local1)
140 renamable $r8d = LEA64_32r killed renamable $r14, 1, $noreg, 3, $noreg, debug-location !24
141 renamable $r9d = LEA64_32r killed renamable $r15, 1, renamable $rbx, 0, $noreg, debug-location !24
142 DBG_VALUE $rsp, $noreg, !18, !DIExpression(DW_OP_plus_uconst, 12, DW_OP_deref), debug-location !24
143 renamable $rdi = LEA64r $rsp, 1, $noreg, 12, $noreg
144 $esi = MOV32rr $ebx, implicit killed $rbx, debug-location !24
145 $edx = MOV32ri 10, debug-location !24
146 $ecx = MOV32ri 15, debug-location !24
147 CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $esi, implicit $edx, implicit killed $ecx, implicit $r8d, implicit $r9d, implicit-def $rsp, implicit-def $ssp, debug-location !24
148 $rsp = frame-destroy ADD64ri8 $rsp, 16, implicit-def dead $eflags, debug-location !24
149 CFI_INSTRUCTION def_cfa_offset 32, debug-location !24
150 $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !24
151 CFI_INSTRUCTION def_cfa_offset 24, debug-location !24
152 $r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !24
153 CFI_INSTRUCTION def_cfa_offset 16, debug-location !24
154 $r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !24
155 CFI_INSTRUCTION def_cfa_offset 8, debug-location !24
156 RETQ debug-location !24
157
158 ...
1313
1414 ; REQUIRES: object-emission
1515 ; RUN: %llc_dwarf -mtriple=x86_64-- < %s -o - | FileCheck %s -check-prefix=ASM
16 ; RUN: %llc_dwarf -mtriple=x86_64-- < %s -filetype=obj -o %t.o
16 ; RUN: %llc_dwarf -debugger-tune=lldb -mtriple=x86_64-- < %s -filetype=obj -o %t.o
1717 ; RUN: llvm-dwarfdump %t.o -o - | FileCheck %s -check-prefix=OBJ -implicit-check-not=DW_TAG_call_site
1818 ; RUN: llvm-dwarfdump -verify %t.o 2>&1 | FileCheck %s -check-prefix=VERIFY
1919 ; RUN: llvm-dwarfdump -statistics %t.o | FileCheck %s -check-prefix=STATS
2020 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis -o /dev/null
2121
2222 ; VERIFY: No errors.
23 ; STATS: "call site entries":5
23 ; STATS: "call site DIEs":6
2424
2525 @sink = global i32 0, align 4, !dbg !0
2626
8484 ; OBJ: DW_TAG_call_site
8585 ; OBJ: DW_AT_call_origin ([[foo_sp]])
8686 ; OBJ: DW_AT_call_return_pc
87 ; OBJ: DW_TAG_call_site
88 ; OBJ: DW_AT_call_target
89 ; OBJ: DW_AT_call_return_pc
8790 define i32 @main() !dbg !29 {
8891 entry:
8992 call void @_Z3foov(), !dbg !32
0 ; RUN: llc -debug-entry-values %s -o - -filetype=obj \
1 ; RUN: | llvm-dwarfdump -statistics - | FileCheck %s
2 ;
3 ; The LLVM IR file was generated on this source code by using
4 ; option '-femit-param-entry-values'.
5 ;
6 ; extern void foo(int *a, int b, int c, int d, int e, int f);
7 ; extern int getVal();
8 ;
9 ; void baa(int arg1, int arg2, int arg3) {
10 ; int local1 = getVal();
11 ; foo(&local1, arg2, 10, 15, arg3 + 3, arg1 + arg2);
12 ; }
13 ;
14 ; CHECK: "call site DIEs":2
15 ; CHECK-SAME: "call site parameter DIEs":6
16 ;
17 ; ModuleID = 'test.c'
18 source_filename = "test.c"
19 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
20 target triple = "x86_64-unknown-linux-gnu"
21
22 ; Function Attrs: nounwind uwtable
23 define dso_local void @baa(i32 %arg1, i32 %arg2, i32 %arg3) local_unnamed_addr #0 !dbg !10 {
24 entry:
25 %local1 = alloca i32, align 4
26 call void @llvm.dbg.value(metadata i32 %arg1, metadata !15, metadata !DIExpression()), !dbg !19
27 call void @llvm.dbg.value(metadata i32 %arg2, metadata !16, metadata !DIExpression()), !dbg !20
28 call void @llvm.dbg.value(metadata i32 %arg3, metadata !17, metadata !DIExpression()), !dbg !21
29 %0 = bitcast i32* %local1 to i8*, !dbg !22
30 %call = tail call i32 (...) @getVal(), !dbg !23
31 call void @llvm.dbg.value(metadata i32 %call, metadata !18, metadata !DIExpression()), !dbg !24
32 store i32 %call, i32* %local1, align 4, !dbg !24
33 %add = add nsw i32 %arg3, 3, !dbg !24
34 %add1 = add nsw i32 %arg2, %arg1, !dbg !24
35 call void @llvm.dbg.value(metadata i32* %local1, metadata !18, metadata !DIExpression(DW_OP_deref)), !dbg !24
36 call void @foo(i32* nonnull %local1, i32 %arg2, i32 10, i32 15, i32 %add, i32 %add1), !dbg !24
37 ret void, !dbg !24
38 }
39
40 declare !dbg !4 dso_local i32 @getVal(...) local_unnamed_addr
41
42 declare !dbg !5 dso_local void @foo(i32*, i32, i32, i32, i32, i32) local_unnamed_addr
43
44 ; Function Attrs: nounwind readnone speculatable
45 declare void @llvm.dbg.value(metadata, metadata, metadata)
46
47 !llvm.dbg.cu = !{!0}
48 !llvm.module.flags = !{!6, !7, !8}
49 !llvm.ident = !{!9}
50
51 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None)
52 !1 = !DIFile(filename: "test.c", directory: "/dir")
53 !2 = !{}
54 !3 = !{!4, !5}
55 !4 = !DISubprogram(name: "getVal", scope: !1, file: !1, line: 2, spFlags: DISPFlagOptimized, retainedNodes: !2)
56 !5 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
57 !6 = !{i32 2, !"Dwarf Version", i32 4}
58 !7 = !{i32 2, !"Debug Info Version", i32 3}
59 !8 = !{i32 1, !"wchar_size", i32 4}
60 !9 = !{!"clang version 9.0.0"}
61 !10 = distinct !DISubprogram(name: "baa", scope: !1, file: !1, line: 4, type: !11, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !14)
62 !11 = !DISubroutineType(types: !12)
63 !12 = !{null, !13, !13, !13}
64 !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
65 !14 = !{!15, !16, !17, !18}
66 !15 = !DILocalVariable(name: "arg1", arg: 1, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
67 !16 = !DILocalVariable(name: "arg2", arg: 2, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
68 !17 = !DILocalVariable(name: "arg3", arg: 3, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
69 !18 = !DILocalVariable(name: "local1", scope: !10, file: !1, line: 5, type: !13)
70 !19 = !DILocation(line: 4, column: 14, scope: !10)
71 !20 = !DILocation(line: 4, column: 24, scope: !10)
72 !21 = !DILocation(line: 4, column: 34, scope: !10)
73 !22 = !DILocation(line: 5, column: 3, scope: !10)
74 !23 = !DILocation(line: 5, column: 16, scope: !10)
75 !24 = !DILocation(line: 5, column: 7, scope: !10)
5555 /// Total number of PC range bytes in each variable's enclosing scope,
5656 /// starting from the first definition of the variable.
5757 unsigned ScopeBytesFromFirstDefinition = 0;
58 /// Total number of call site entries (DW_TAG_call_site) or
59 /// (DW_AT_call_file & DW_AT_call_line).
58 /// Total number of call site entries (DW_AT_call_file & DW_AT_call_line).
6059 unsigned CallSiteEntries = 0;
60 /// Total number of call site DIEs (DW_TAG_call_site).
61 unsigned CallSiteDIEs = 0;
62 /// Total number of call site parameter DIEs (DW_TAG_call_site_parameter).
63 unsigned CallSiteParamDIEs = 0;
6164 /// Total byte size of concrete functions. This byte size includes
6265 /// inline functions contained in the concrete functions.
6366 uint64_t FunctionSize = 0;
9396 uint64_t BytesCovered = 0;
9497 uint64_t OffsetToFirstDefinition = 0;
9598
96 if (Die.getTag() == dwarf::DW_TAG_call_site) {
97 GlobalStats.CallSiteEntries++;
99 if (Die.getTag() == dwarf::DW_TAG_call_site ||
100 Die.getTag() == dwarf::DW_TAG_GNU_call_site) {
101 GlobalStats.CallSiteDIEs++;
102 return;
103 }
104
105 if (Die.getTag() == dwarf::DW_TAG_call_site_parameter ||
106 Die.getTag() == dwarf::DW_TAG_GNU_call_site_parameter) {
107 GlobalStats.CallSiteParamDIEs++;
98108 return;
99109 }
100110
386396 printDatum(OS, "source variables", VarParamTotal);
387397 printDatum(OS, "variables with location", VarParamWithLoc);
388398 printDatum(OS, "call site entries", GlobalStats.CallSiteEntries);
399 printDatum(OS, "call site DIEs", GlobalStats.CallSiteDIEs);
400 printDatum(OS, "call site parameter DIEs", GlobalStats.CallSiteParamDIEs);
389401 printDatum(OS, "scope bytes total",
390402 GlobalStats.ScopeBytesFromFirstDefinition);
391403 printDatum(OS, "scope bytes covered", GlobalStats.ScopeBytesCovered);