llvm.org GIT mirror llvm / 9e7e735
[DwarfDebug] Dump call site debug info Dump the DWARF information about call sites and call site parameters into debug info sections. The patch also provides an interface for the interpretation of instructions that could load values of a call site parameters in order to generate DWARF about the call site parameters. ([13/13] Introduce the debug entry values.) Co-authored-by: Ananth Sowda <asowda@cisco.com> Co-authored-by: Nikola Prica <nikola.prica@rt-rk.com> Co-authored-by: Ivan Baev <ibaev@cisco.com> Differential Revision: https://reviews.llvm.org/D60716 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365467 91177308-0d34-0410-b5e6-96231b3b80d8 Djordje Todorovic a month ago
23 changed file(s) with 1103 addition(s) and 52 deletion(s). Raw diff Collapse all Expand all
47544754 ``DW_OP_entry_value`` may also appear after the ``AsmPrinter`` pass when
47554755 a call site parameter value (``DW_AT_call_site_parameter_value``)
47564756 is represented as entry value of the parameter.
4757 - ``DW_OP_reg`` (or ``DW_OP_regx``) represents a physical register location.
4758 The opcode is only generated by the ``AsmPrinter`` pass to describe
4759 call site parameter value which requires an expression over two registers.
47574760
47584761 DWARF specifies three kinds of simple location descriptions: Register, memory,
47594762 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 RHS description of parameter's loading instruction \p MI.
1696 virtual Optional
1697 describeLoadedValue(const MachineInstr &MI) const;
1698
16931699 private:
16941700 unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
16951701 unsigned CatchRetOpcode;
530530 /// prior to a call and is guaranteed to be restored (also by the caller)
531531 /// after the call.
532532 virtual bool isCallerPreservedPhysReg(unsigned PhysReg,
533 const MachineFunction &MF) const {
534 return false;
535 }
533 const MachineFunction &MF) const;
536534
537535 /// Prior to adding the live-out mask to a stackmap or patchpoint
538536 /// instruction, provide the target the opportunity to adjust it (mainly to
889889 ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
890890 }
891891
892 dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUCallSiteTag(dwarf::Tag Tag) {
893 bool ApplyGNUExtensions = DD->getDwarfVersion() == 4 && DD->tuneForGDB();
894 if (!ApplyGNUExtensions)
895 return Tag;
896 switch(Tag) {
897 case dwarf::DW_TAG_call_site:
898 return dwarf::DW_TAG_GNU_call_site;
899 case dwarf::DW_TAG_call_site_parameter:
900 return dwarf::DW_TAG_GNU_call_site_parameter;
901 default:
902 llvm_unreachable("unhandled call site tag");
903 }
904 }
905
906 dwarf::Attribute DwarfCompileUnit::getDwarf5OrGNUCallSiteAttr(dwarf::Attribute Attr) {
907 bool ApplyGNUExtensions = DD->getDwarfVersion() == 4 && DD->tuneForGDB();
908 if (!ApplyGNUExtensions)
909 return Attr;
910 switch(Attr) {
911 case dwarf::DW_AT_call_all_calls:
912 return dwarf::DW_AT_GNU_all_call_sites;
913 case dwarf::DW_AT_call_target:
914 return dwarf::DW_AT_GNU_call_site_target;
915 case dwarf::DW_AT_call_origin:
916 return dwarf::DW_AT_abstract_origin;
917 case dwarf::DW_AT_call_pc:
918 return dwarf::DW_AT_low_pc;
919 case dwarf::DW_AT_call_value:
920 return dwarf::DW_AT_GNU_call_site_value;
921 case dwarf::DW_AT_call_tail_call:
922 return dwarf::DW_AT_GNU_tail_call;
923 default:
924 llvm_unreachable("unhandled call site attribute");
925 }
926 }
927
892928 DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
893 const DISubprogram &CalleeSP,
929 const DISubprogram *CalleeSP,
894930 bool IsTail,
895 const MCExpr *PCOffset) {
931 const MCSymbol *PCAddr,
932 const MCExpr *PCOffset,
933 unsigned CallReg) {
896934 // Insert a call site entry DIE within ScopeDIE.
897935 DIE &CallSiteDIE =
898 createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr);
899
900 // For the purposes of showing tail call frames in backtraces, a key piece of
901 // information is DW_AT_call_origin, a pointer to the callee DIE.
902 DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP);
903 assert(CalleeDIE && "Could not create DIE for call site entry origin");
904 addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE);
905
906 if (IsTail) {
936 createAndAddDIE(getDwarf5OrGNUCallSiteTag(dwarf::DW_TAG_call_site),
937 ScopeDIE, nullptr);
938
939 if (CallReg) {
940 // Indirect call.
941 addAddress(CallSiteDIE, 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, getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_origin),
947 *CalleeDIE);
948 }
949
950 if (IsTail)
907951 // Attach DW_AT_call_tail_call to tail calls for standards compliance.
908 addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call);
909 } else {
910 // Attach the return PC to allow the debugger to disambiguate call paths
911 // from one function to another.
952 addFlag(CallSiteDIE, getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_tail_call));
953
954 // Attach the return PC to allow the debugger to disambiguate call paths
955 // from one function to another.
956 if (DD->getDwarfVersion() == 4 && DD->tuneForGDB()) {
957 assert(PCAddr && "Missing PC information for a call");
958 addLabelAddress(CallSiteDIE, dwarf::DW_AT_low_pc, PCAddr);
959 } else if (!IsTail || DD->tuneForGDB()) {
912960 assert(PCOffset && "Missing return PC information for a call");
913961 addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset);
914962 }
963
915964 return CallSiteDIE;
965 }
966
967 void DwarfCompileUnit::constructCallSiteParmEntryDIEs(
968 DIE &CallSiteDIE, SmallVector &Params) {
969 for (auto &Param : Params) {
970 unsigned Register = Param.getRegister();
971 auto CallSiteDieParam =
972 DIE::get(DIEValueAllocator,
973 getDwarf5OrGNUCallSiteTag(dwarf::DW_TAG_call_site_parameter));
974 insertDIE(CallSiteDieParam);
975 addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
976 MachineLocation(Register));
977
978 DIELoc *Loc = new (DIEValueAllocator) DIELoc;
979 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
980 DwarfExpr.setCallSiteParamValueFlag();
981
982 DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);
983
984 addBlock(*CallSiteDieParam,
985 getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_value),
986 DwarfExpr.finalize());
987
988 CallSiteDIE.addChild(CallSiteDieParam);
989 }
916990 }
917991
918992 DIE *DwarfCompileUnit::constructImportedEntityDIE(
226226
227227 void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
228228
229 dwarf::Tag getDwarf5OrGNUCallSiteTag(dwarf::Tag Tag);
230 dwarf::Attribute getDwarf5OrGNUCallSiteAttr(dwarf::Attribute Attr);
231
229232 /// Construct a call site entry DIE describing a call within \p Scope to a
230233 /// 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
232 /// function-local offset to PC value after the call instruction.
233 DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram &CalleeSP,
234 bool IsTail, const MCExpr *PCOffset);
234 /// a tail call. \p PCAddr (used for GDB + DWARF 4 tuning) points to
235 /// the PC value after the call instruction. \p PCOffset (used for
236 /// cases other than GDB + DWARF 4 tuning) must be non-zero for non-tail calls
237 /// (in the case of non-gdb tuning) or be the function-local offset to PC value
238 /// after the call instruction. \p CallReg is a register location
239 /// for an indirect call.
240 DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,
241 bool IsTail, const MCSymbol *PCAddr,
242 const MCExpr *PCOffset, unsigned CallReg);
243 void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE,
244 SmallVector &Params);
235245
236246 /// Construct import_module DIE.
237247 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 ArgsRegsForProcess;
578 for (auto ArgReg : CallFwdRegsInfo->second)
579 ArgsRegsForProcess.insert(ArgReg.Reg);
580
581 // If we did not find loading a value into forwarding registers
582 // that means we can try generating 'DW_OP_entry_value' for the argument
583 // if a call is within entry MBB.
584 DenseMap RegsForEntryValues;
585 bool ShouldTryEmitEntryVals = MBB->getIterator() == MF->begin();
586
587 // Return true if it is an instruction over a parameter's forwarding
588 // register that clobbers it.
589 auto shouldInterpret = [&](const MachineInstr &MI) -> unsigned {
590 if (MI.isDebugInstr())
591 return 0;
592 // If a MI clobbers a forwarding reg try to interpret
593 // a value loaded into the reg.
594 for (const MachineOperand &MO : MI.operands()) {
595 if (MO.isReg() && MO.isDef() && MO.getReg() &&
596 TRI->isPhysicalRegister(MO.getReg())) {
597 for (auto FwdReg : ArgsRegsForProcess)
598 if (TRI->regsOverlap(FwdReg, MO.getReg()))
599 return FwdReg;
600 }
601 }
602
603 return 0;
604 };
605
606 auto finishCallSiteParam = [&](DbgValueLoc &DbgLocVal,
607 unsigned &Reg) {
608 unsigned FwdReg = Reg;
609 if (ShouldTryEmitEntryVals && RegsForEntryValues.count(Reg))
610 FwdReg = RegsForEntryValues[Reg];
611 DbgCallSiteParam CSParm(FwdReg, DbgLocVal);
612 Params.push_back(CSParm);
613 NumCSParams++;
614 };
615
616 // Search for a loading value in forwaring registers.
617 while (I != MBB->rend()) {
618 // If the next instruction is a call we can not
619 // interpret parameter's forwarding registers or
620 // we finished interpretation of all parameters.
621 if (I->isCall())
622 return;
623
624 if (ArgsRegsForProcess.empty())
625 return;
626
627 if (unsigned Reg = shouldInterpret(*I)) {
628 ArgsRegsForProcess.erase(Reg);
629 const MachineOperand *Op;
630 DIExpression *Expr;
631 if (auto ParamValue = TII->describeLoadedValue(*I)) {
632 Op = ParamValue->first;
633 Expr = ParamValue->second;
634 if (Op->isImm()) {
635 unsigned Val = Op->getImm();
636 DbgValueLoc DbgLocVal(Expr, Val);
637 finishCallSiteParam(DbgLocVal, Reg);
638 } else if (Op->isReg()) {
639 unsigned RegLoc = Op->getReg();
640 unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
641 unsigned FP = TRI->getFrameRegister(*MF);
642 bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP);
643 if (TRI->isCallerPreservedPhysReg(RegLoc, *MF) || IsSPorFP) {
644 DbgValueLoc DbgLocVal(
645 Expr, MachineLocation(RegLoc, IsSPorFP));
646 finishCallSiteParam(DbgLocVal, Reg);
647 } else if (ShouldTryEmitEntryVals) {
648 ArgsRegsForProcess.insert(RegLoc);
649 RegsForEntryValues[RegLoc] = Reg;
650 }
651 }
652 }
653 }
654
655 ++I;
656 }
657
658 // Emit call site parameter's value as entry value.
659 if (ShouldTryEmitEntryVals) {
660 DIExpression *EntryExpr = DIExpression::get(MF->getFunction().getContext(),
661 {dwarf::DW_OP_entry_value, 1});
662 for (auto RegEntry : ArgsRegsForProcess) {
663 unsigned FwdReg = RegsForEntryValues.count(RegEntry)
664 ? RegsForEntryValues[RegEntry]
665 : RegEntry;
666 DbgValueLoc DbgLocVal(EntryExpr, MachineLocation(RegEntry));
667 DbgCallSiteParam CSParm(FwdReg, DbgLocVal);
668 Params.push_back(CSParm);
669 NumCSParams++;
670 }
671 }
672 }
673
553674 void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
554675 DwarfCompileUnit &CU, DIE &ScopeDIE,
555676 const MachineFunction &MF) {
562683 // for both tail and non-tail calls. Don't use DW_AT_call_all_source_calls
563684 // because one of its requirements is not met: call site entries for
564685 // optimized-out calls are elided.
565 CU.addFlag(ScopeDIE, dwarf::DW_AT_call_all_calls);
686 CU.addFlag(ScopeDIE,
687 CU.getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_all_calls));
566688
567689 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
568690 assert(TII && "TargetInstrInfo not found: cannot label tail calls");
691 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
692 bool ApplyGNUExtensions = getDwarfVersion() == 4 && tuneForGDB();
569693
570694 // Emit call site entries for each call or tail call in the function.
571695 for (const MachineBasicBlock &MBB : MF) {
580704 return;
581705
582706 // If this is a direct call, find the callee's subprogram.
707 // In the case of an indirect call find the register that holds
708 // the callee.
583709 const MachineOperand &CalleeOp = MI.getOperand(0);
584 if (!CalleeOp.isGlobal())
710 if (!CalleeOp.isGlobal() && !CalleeOp.isReg())
585711 continue;
586 const Function *CalleeDecl = dyn_cast(CalleeOp.getGlobal());
587 if (!CalleeDecl || !CalleeDecl->getSubprogram())
588 continue;
712
713 unsigned CallReg = 0;
714 const DISubprogram *CalleeSP = nullptr;
715 const Function *CalleeDecl = nullptr;
716 if (CalleeOp.isReg()) {
717 CallReg = CalleeOp.getReg();
718 if (!CallReg)
719 continue;
720 } else {
721 CalleeDecl = dyn_cast(CalleeOp.getGlobal());
722 if (!CalleeDecl || !CalleeDecl->getSubprogram())
723 continue;
724 CalleeSP = CalleeDecl->getSubprogram();
725 }
589726
590727 // TODO: Omit call site entries for runtime calls (objc_msgSend, etc).
591 // TODO: Add support for indirect calls.
592728
593729 bool IsTail = TII->isTailCall(MI);
594730
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.
731 // For tail calls, for non-gdb tuning, no return PC information is needed.
732 // For regular calls (and tail calls in GDB tuning), the return PC
733 // is needed to disambiguate paths in the call graph which could lead to
734 // some target function.
598735 const MCExpr *PCOffset =
599 IsTail ? nullptr : getFunctionLocalOffsetAfterInsn(&MI);
600
601 assert((IsTail || PCOffset) && "Call without return PC information");
736 (IsTail && !tuneForGDB()) ? nullptr
737 : getFunctionLocalOffsetAfterInsn(&MI);
738
739 // Address of a call-like instruction for a normal call or a jump-like
740 // instruction for a tail call. This is needed for GDB + DWARF 4 tuning.
741 const MCSymbol *PCAddr =
742 ApplyGNUExtensions ? const_cast(getLabelAfterInsn(&MI))
743 : nullptr;
744
745 assert((IsTail || PCOffset || PCAddr) &&
746 "Call without return PC information");
747
602748 LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> "
603 << CalleeDecl->getName() << (IsTail ? " [tail]" : "")
749 << (CalleeDecl ? CalleeDecl->getName()
750 : StringRef(TRI->getName(CallReg)))
751 << (IsTail ? " [IsTail]" : "")
604752 << "\n");
605 CU.constructCallSiteEntryDIE(ScopeDIE, *CalleeDecl->getSubprogram(),
606 IsTail, PCOffset);
753
754 DIE &CallSiteDIE =
755 CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, IsTail, PCAddr,
756 PCOffset, CallReg);
757
758 // For now only GDB supports call site parameter debug info.
759 if (Asm->TM.Options.EnableDebugEntryValues &&
760 tuneForGDB()) {
761 ParamSet Params;
762 // Try to interpret values of call site parameters.
763 collectCallSiteParameters(&MI, Params);
764 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
765 }
607766 }
608767 }
609768 }
253253 }
254254 };
255255
256 /// Used for tracking debug info about call site parameters.
257 class DbgCallSiteParam {
258 private:
259 unsigned Register;
260 DbgValueLoc Value;
261 public:
262 DbgCallSiteParam(unsigned Reg, DbgValueLoc Val)
263 : Register(Reg), Value(Val) {}
264
265 unsigned getRegister() { return Register; }
266 DbgValueLoc getValue() { return Value; }
267 };
268
269 /// Collection used for storing debug call site parameters.
270 using ParamSet = SmallVector;
271
256272 /// Helper used to pair up a symbol and its DWARF compile unit.
257273 struct SymbolCU {
258274 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
244 // emit a call site parameter expression and if that expression
245 // is just a register location, emit it with addBReg and offset 0,
246 // because we should emit a DWARF expression representing a value,
247 // rather than a location.
248 if (!isMemoryLocation() && !HasComplexExpression &&
249 (!isParameterValue() || isEntryValue())) {
245250 for (auto &Reg : DwarfRegs) {
246251 if (Reg.DwarfRegNo >= 0)
247252 addReg(Reg.DwarfRegNo, Reg.Comment);
248253 addOpPiece(Reg.Size);
249254 }
250255
251 if (isEntryValue() && DwarfVersion >= 4)
256 if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4)
252257 emitOp(dwarf::DW_OP_stack_value);
253258
254259 DwarfRegs.clear();
339344
340345 while (ExprCursor) {
341346 auto Op = ExprCursor.take();
342 switch (Op->getOp()) {
347 uint64_t OpNum = Op->getOp();
348 if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
349 if (isParameterValue())
350 addBReg(OpNum - dwarf::DW_OP_reg0, 0);
351 else
352 emitOp(OpNum);
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 if (isParameterValue()) {
476 emitOp(dwarf::DW_OP_bregx);
477 emitUnsigned(Op->getArg(0));
478 emitSigned(Op->getArg(1));
479 } else {
480 emitOp(dwarf::DW_OP_regx);
481 emitUnsigned(Op->getArg(0));
482 }
483 break;
460484 default:
461485 llvm_unreachable("unhandled opcode found in expression");
462486 }
463487 }
464488
465 if (isImplicitLocation())
489 if (isImplicitLocation() && !isParameterValue())
466490 // Turn this into an implicit location description.
467491 addStackValue();
468492 }
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 MachineOperand *Op = nullptr;
1126 DIExpression *Expr = nullptr;
1127
1128 const MachineOperand *SrcRegOp, *DestRegOp;
1129 const MachineFunction *MF = MI.getMF();
1130 if (isCopyInstr(MI, SrcRegOp, DestRegOp)) {
1131 Expr = DIExpression::get(MF->getFunction().getContext(), {});
1132 Op = SrcRegOp;
1133 return ParamLoadedValue(Op, Expr);
1134 } else if (MI.isMoveImmediate()) {
1135 Expr = DIExpression::get(MF->getFunction().getContext(), {});
1136 Op = &MI.getOperand(1);
1137 return ParamLoadedValue(Op, Expr);
1138 } else if (MI.hasOneMemOperand()) {
1139 int64_t Offset;
1140 const auto &TRI = MF->getSubtarget().getRegisterInfo();
1141 const auto &TII = MF->getSubtarget().getInstrInfo();
1142 const MachineOperand *BaseOp;
1143 if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, TRI))
1144 return None;
1145 unsigned CastedOffset = static_cast(Offset);
1146 if (Offset > 0)
1147 Expr = DIExpression::get(
1148 MF->getFunction().getContext(),
1149 {dwarf::DW_OP_plus_uconst, CastedOffset, dwarf::DW_OP_deref});
1150 else
1151 Expr = DIExpression::get(MF->getFunction().getContext(),
1152 {dwarf::DW_OP_constu, -CastedOffset,
1153 dwarf::DW_OP_minus, dwarf::DW_OP_deref});
1154
1155 Op = BaseOp;
1156 return ParamLoadedValue(Op, Expr);
1157 }
1158
1159 return None;
1160 }
1161
11221162 /// Both DefMI and UseMI must be valid. By default, call directly to the
11231163 /// itinerary. This may be overriden by the target.
11241164 int TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
432432 return false;
433433 }
434434
435 bool
436 TargetRegisterInfo::isCallerPreservedPhysReg(unsigned PhysReg,
437 const MachineFunction &MF) const {
438 if (PhysReg == 0)
439 return false;
440 const uint32_t *callerPreservedRegs =
441 getCallPreservedMask(MF, MF.getFunction().getCallingConv());
442 if (callerPreservedRegs) {
443 assert(isPhysicalRegister(PhysReg) && "Expected physical register");
444 return (callerPreservedRegs[PhysReg / 32] >> PhysReg % 32) & 1;
445 }
446 return false;
447 }
448
435449 bool TargetRegisterInfo::canRealignStack(const MachineFunction &MF) const {
436450 return !MF.getFunction().hasFnAttribute("no-realign-stack");
437451 }
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;
832832 case dwarf::DW_OP_LLVM_fragment:
833833 return 3;
834834 case dwarf::DW_OP_constu:
835 case dwarf::DW_OP_consts:
835836 case dwarf::DW_OP_deref_size:
836837 case dwarf::DW_OP_plus_uconst:
837838 case dwarf::DW_OP_LLVM_tag_offset:
838839 case dwarf::DW_OP_entry_value:
840 case dwarf::DW_OP_regx:
839841 return 2;
840842 default:
841843 return 1;
848850 if (I->get() + I->getSize() > E->get())
849851 return false;
850852
853 uint64_t Op = I->getOp();
854 if (Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31)
855 continue;
856
851857 // Check that the operand is valid.
852 switch (I->getOp()) {
858 switch (Op) {
853859 default:
854860 return false;
855861 case dwarf::DW_OP_LLVM_fragment:
904910 case dwarf::DW_OP_lit0:
905911 case dwarf::DW_OP_not:
906912 case dwarf::DW_OP_dup:
913 case dwarf::DW_OP_regx:
907914 break;
908915 }
909916 }
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"
73177317 }
73187318 }
73197319
7320 Optional
7321 X86InstrInfo::describeLoadedValue(const MachineInstr &MI) const {
7322 const MachineOperand *Op = nullptr;
7323 DIExpression *Expr = nullptr;
7324
7325 switch (MI.getOpcode()) {
7326 case X86::LEA32r:
7327 case X86::LEA64r:
7328 case X86::LEA64_32r: {
7329 // Operand 4 could be global address. For now we do not support
7330 // such situation.
7331 if (!MI.getOperand(4).isImm() || !MI.getOperand(2).isImm())
7332 return None;
7333
7334 const MachineOperand &Op1 = MI.getOperand(1);
7335 const MachineOperand &Op2 = MI.getOperand(3);
7336 const TargetRegisterInfo *TRI = &getRegisterInfo();
7337 assert(Op2.isReg() &&
7338 (Op2.getReg() == X86::NoRegister ||
7339 TargetRegisterInfo::isPhysicalRegister(Op2.getReg())));
7340
7341 // Omit situations like:
7342 // %rsi = lea %rsi, 4, ...
7343 if ((Op1.isReg() && Op1.getReg() == MI.getOperand(0).getReg()) ||
7344 Op2.getReg() == MI.getOperand(0).getReg())
7345 return None;
7346 else if ((Op1.isReg() && Op1.getReg() != X86::NoRegister &&
7347 TRI->regsOverlap(Op1.getReg(), MI.getOperand(0).getReg())) ||
7348 (Op2.getReg() != X86::NoRegister &&
7349 TRI->regsOverlap(Op2.getReg(), MI.getOperand(0).getReg())))
7350 return None;
7351
7352 int64_t Coef = MI.getOperand(2).getImm();
7353 int64_t Offset = MI.getOperand(4).getImm();
7354 SmallVector Elements;
7355
7356 if ((Op1.isReg() && Op1.getReg() != X86::NoRegister)) {
7357 Op = &Op1;
7358 } else if (Op1.isFI())
7359 Op = &Op1;
7360
7361 if (Op && Op->isReg() && Op->getReg() == Op2.getReg() && Coef > 0) {
7362 Elements.push_back(dwarf::DW_OP_constu);
7363 Elements.push_back(Coef + 1);
7364 Elements.push_back(dwarf::DW_OP_mul);
7365 } else {
7366 if (Op && Op2.getReg() != X86::NoRegister) {
7367 int dwarfReg = TRI->getDwarfRegNum(Op2.getReg(), false);
7368 if (dwarfReg < 0)
7369 return None;
7370 else if (dwarfReg < 32)
7371 Elements.push_back(dwarf::DW_OP_reg0 + dwarfReg);
7372 else {
7373 Elements.push_back(dwarf::DW_OP_regx);
7374 Elements.push_back(dwarfReg);
7375 }
7376 } else if (!Op) {
7377 assert(Op2.getReg() != X86::NoRegister);
7378 Op = &Op2;
7379 }
7380
7381 if (Coef > 1) {
7382 assert(Op2.getReg() != X86::NoRegister);
7383 Elements.push_back(dwarf::DW_OP_constu);
7384 Elements.push_back(Coef);
7385 Elements.push_back(dwarf::DW_OP_mul);
7386 }
7387
7388 if (((Op1.isReg() && Op1.getReg() != X86::NoRegister) || Op1.isFI()) &&
7389 Op2.getReg() != X86::NoRegister) {
7390 Elements.push_back(dwarf::DW_OP_plus);
7391 }
7392 }
7393
7394 if (Offset < 0) {
7395 Elements.push_back(dwarf::DW_OP_constu);
7396 Elements.push_back(-Offset);
7397 Elements.push_back(dwarf::DW_OP_minus);
7398 } else if (Offset > 0) {
7399 Elements.push_back(dwarf::DW_OP_constu);
7400 Elements.push_back(Offset);
7401 Elements.push_back(dwarf::DW_OP_plus);
7402 }
7403
7404 Expr = DIExpression::get(MI.getMF()->getFunction().getContext(), Elements);
7405 return ParamLoadedValue(Op, Expr);;
7406 }
7407 default:
7408 return TargetInstrInfo::describeLoadedValue(MI);
7409 }
7410 }
7411
73207412 /// This is an architecture-specific helper function of reassociateOps.
73217413 /// Set special operand attributes for new instructions after reassociation.
73227414 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: DW_TAG_GNU_call_site
18 # CHECK-NEXT: DW_AT_abstract_origin {{.*}}"foo"
19 # CHECK-NEXT: DW_AT_low_pc
20 # CHECK-EMPTY:
21 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
22 # CHECK-NEXT: DW_AT_location (DW_OP_reg2 RCX)
23 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +8, DW_OP_deref)
24 # CHECK-EMPTY:
25 # CHECK-NEXT: DW_TAG_GNU_call_site_parameter
26 # CHECK-NEXT: DW_AT_location (DW_OP_reg4 RSI)
27 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit4)
28 # CHECK-NOT: DW_TAG_GNU_call_site_parameter
29 #
30 # Check that call site interpretation analysis can interpret instructions such
31 # as move immediate, register to register moves, stack loading and LEA
32 # instructions. Last negative check should verify that we are not producing
33 # interpretation for RDX register since its loaded value is call clobberable.
34 # Also check that we are generating proper call site debug entities.
35 --- |
36 ; ModuleID = 'dbgcall-site-interpretation.c'
37 source_filename = "dbgcall-site-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 ; Function Attrs: nounwind uwtable
42 define dso_local i32 @baa(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) local_unnamed_addr !dbg !9 {
43 entry:
44 %arg3.addr = alloca i32, align 4
45 %local2 = alloca i32, align 4
46 call void @llvm.dbg.value(metadata i32 %arg1, metadata !14, metadata !DIExpression()), !dbg !21
47 call void @llvm.dbg.value(metadata i32 %arg2, metadata !15, metadata !DIExpression()), !dbg !21
48 call void @llvm.dbg.value(metadata i32 %arg3, metadata !16, metadata !DIExpression()), !dbg !21
49 store i32 %arg3, i32* %arg3.addr, align 4
50 call void @llvm.dbg.value(metadata i32 %arg4, metadata !17, metadata !DIExpression()), !dbg !21
51 %0 = bitcast i32* %local2 to i8*, !dbg !21
52 call void @llvm.dbg.value(metadata i32* %arg3.addr, metadata !16, metadata !DIExpression(DW_OP_deref)), !dbg !21
53 %call = call i32 @foo(i32 %arg1, i32 %arg2, i32* nonnull %arg3.addr, i32 %arg4), !dbg !21
54 call void @llvm.dbg.value(metadata i32 %call, metadata !18, metadata !DIExpression()), !dbg !21
55 %cmp = icmp sgt i32 %arg1, %arg2, !dbg !21
56 %1 = load i32, i32* %arg3.addr, align 4, !dbg !21
57 call void @llvm.dbg.value(metadata i32 %1, metadata !16, metadata !DIExpression()), !dbg !21
58 %add = add nsw i32 %1, %arg1, !dbg !21
59 %add1 = add nsw i32 %arg4, %arg2, !dbg !21
60 %local1.0 = select i1 %cmp, i32 %add, i32 %add1, !dbg !21
61 call void @llvm.dbg.value(metadata i32 %local1.0, metadata !18, metadata !DIExpression()), !dbg !21
62 %rem = srem i32 %1, %arg1, !dbg !21
63 %tobool = icmp eq i32 %rem, 0, !dbg !21
64 %mul = mul nsw i32 %1, %arg1, !dbg !21
65 %add3 = add nsw i32 %1, %arg4, !dbg !21
66 %storemerge = select i1 %tobool, i32 %mul, i32 %add3, !dbg !21
67 call void @llvm.dbg.value(metadata i32 %storemerge, metadata !19, metadata !DIExpression()), !dbg !21
68 store i32 %storemerge, i32* %local2, align 4, !dbg !21
69 %cmp6 = icmp slt i32 %storemerge, %arg4, !dbg !21
70 %local3.0.v = select i1 %cmp6, i32 %local1.0, i32 %arg1, !dbg !21
71 %local3.0 = mul nsw i32 %local3.0.v, %storemerge, !dbg !21
72 call void @llvm.dbg.value(metadata i32 %local3.0, metadata !20, metadata !DIExpression()), !dbg !21
73 call void @llvm.dbg.value(metadata i32* %local2, metadata !19, metadata !DIExpression(DW_OP_deref)), !dbg !21
74 %call12 = call i32 @foo(i32 %local1.0, i32 4, i32* nonnull %local2, i32 %local3.0), !dbg !21
75 call void @llvm.dbg.value(metadata i32 %call12, metadata !14, metadata !DIExpression()), !dbg !21
76 %add13 = add nsw i32 %call12, 4, !dbg !21
77 ret i32 %add13, !dbg !21
78 }
79
80 declare !dbg !4 dso_local i32 @foo(i32, i32, i32*, i32) local_unnamed_addr
81
82 ; Function Attrs: nounwind readnone speculatable
83 declare void @llvm.dbg.value(metadata, metadata, metadata)
84
85 !llvm.dbg.cu = !{!0}
86 !llvm.module.flags = !{!5, !6, !7}
87 !llvm.ident = !{!8}
88
89 !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)
90 !1 = !DIFile(filename: "dbgcall-site-interpretation.c", directory: "/dir")
91 !2 = !{}
92 !3 = !{!4}
93 !4 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 9, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
94 !5 = !{i32 2, !"Dwarf Version", i32 4}
95 !6 = !{i32 2, !"Debug Info Version", i32 3}
96 !7 = !{i32 1, !"wchar_size", i32 4}
97 !8 = !{!"clang version 9.0.0"}
98 !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)
99 !10 = !DISubroutineType(types: !11)
100 !11 = !{!12, !12, !12, !12, !12}
101 !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
102 !13 = !{!14, !15, !16, !17, !18, !19, !20}
103 !14 = !DILocalVariable(name: "arg1", arg: 1, scope: !9, file: !1, line: 10, type: !12)
104 !15 = !DILocalVariable(name: "arg2", arg: 2, scope: !9, file: !1, line: 10, type: !12, flags: DIFlagArgumentNotModified)
105 !16 = !DILocalVariable(name: "arg3", arg: 3, scope: !9, file: !1, line: 10, type: !12)
106 !17 = !DILocalVariable(name: "arg4", arg: 4, scope: !9, file: !1, line: 10, type: !12, flags: DIFlagArgumentNotModified)
107 !18 = !DILocalVariable(name: "local1", scope: !9, file: !1, line: 11, type: !12)
108 !19 = !DILocalVariable(name: "local2", scope: !9, file: !1, line: 11, type: !12)
109 !20 = !DILocalVariable(name: "local3", scope: !9, file: !1, line: 11, type: !12)
110 !21 = !DILocation(line: 10, column: 13, scope: !9)
111
112 ...
113 ---
114 name: baa
115 liveins:
116 - { reg: '$edi', virtual-reg: '' }
117 - { reg: '$esi', virtual-reg: '' }
118 - { reg: '$edx', virtual-reg: '' }
119 - { reg: '$ecx', virtual-reg: '' }
120 callSites:
121 - { bb: 0, offset: 23, fwdArgRegs:
122 - { arg: 0, reg: '$edi' }
123 - { arg: 1, reg: '$esi' }
124 - { arg: 2, reg: '$rdx' }
125 - { arg: 3, reg: '$ecx' } }
126 - { bb: 0, offset: 49, fwdArgRegs:
127 - { arg: 0, reg: '$edi' }
128 - { arg: 1, reg: '$esi' }
129 - { arg: 2, reg: '$rdx' }
130 - { arg: 3, reg: '$ecx' } }
131 body: |
132 bb.0.entry:
133 liveins: $ecx, $edi, $edx, $esi, $r15, $r14, $rbx
134
135 DBG_VALUE $edi, $noreg, !14, !DIExpression(), debug-location !21
136 DBG_VALUE $esi, $noreg, !15, !DIExpression(), debug-location !21
137 DBG_VALUE $edx, $noreg, !16, !DIExpression(), debug-location !21
138 DBG_VALUE $ecx, $noreg, !17, !DIExpression(), debug-location !21
139 frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
140 CFI_INSTRUCTION def_cfa_offset 16
141 frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
142 CFI_INSTRUCTION def_cfa_offset 24
143 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
144 CFI_INSTRUCTION def_cfa_offset 32
145 $rsp = frame-setup SUB64ri8 $rsp, 16, implicit-def dead $eflags
146 CFI_INSTRUCTION def_cfa_offset 48
147 CFI_INSTRUCTION offset $rbx, -32
148 CFI_INSTRUCTION offset $r14, -24
149 CFI_INSTRUCTION offset $r15, -16
150 $r14d = MOV32rr $ecx, implicit-def $r14
151 DBG_VALUE $edx, $noreg, !16, !DIExpression(), debug-location !21
152 $r15d = MOV32rr $esi, implicit-def $r15
153 $ebx = MOV32rr $edi, implicit-def $rbx
154 $edi = MOV32rr $esi
155 MOV32mr $rsp, 1, $noreg, 8, $noreg, killed renamable $edx :: (store 4 into %ir.arg3.addr)
156 renamable $rdx = LEA64r $rsp, 1, $noreg, 8, $noreg
157 renamable $ecx = MOV32rr $r14d,
158 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
159 DBG_VALUE $noreg, $noreg, !18, !DIExpression(), debug-location !21
160 $rdx = MOV64rr renamable $rax
161 $ecx = KILL renamable $ecx, implicit-def $rcx
162 renamable $eax = LEA64_32r renamable $rcx, 1, renamable $rbx, 0, $noreg, debug-location !21
163 renamable $edi = LEA64_32r renamable $r14, 1, renamable $r15, 0, $noreg, debug-location !21
164 CMP32rr renamable $ebx, renamable $r15d, implicit-def $eflags, implicit killed $r15, debug-location !21
165 renamable $edi = CMOV32rr killed renamable $edi, killed renamable $eax, 15, implicit killed $eflags, debug-location !21
166 DBG_VALUE $edi, $noreg, !18, !DIExpression(), debug-location !21
167 $eax = MOV32rr $ecx, debug-location !21
168 CDQ implicit-def $eax, implicit-def $edx, implicit $eax, debug-location !21
169 IDIV32r renamable $ebx, implicit-def dead $eax, implicit-def $edx, implicit-def dead $eflags, implicit $eax, implicit $edx, debug-location !21
170 $eax = MOV32rr $ecx, debug-location !21
171 renamable $eax = nsw IMUL32rr killed renamable $eax, renamable $ebx, implicit-def dead $eflags, debug-location !21
172 renamable $ecx = nsw ADD32rr renamable $ecx, renamable $r14d, implicit-def dead $eflags, implicit killed $rcx, implicit-def $rcx, debug-location !21
173 TEST32rr killed renamable $edx, renamable $edx, implicit-def $eflags, debug-location !21
174 renamable $ecx = CMOV32rr renamable $ecx, killed renamable $eax, 4, implicit killed $eflags, implicit killed $rcx, implicit-def $rcx, debug-location !21
175 DBG_VALUE $ecx, $noreg, !19, !DIExpression(), debug-location !21
176 MOV32mr $rsp, 1, $noreg, 12, $noreg, renamable $ecx, debug-location !21 :: (store 4 into %ir.local2)
177 CMP32rr renamable $ecx, renamable $r14d, implicit-def $eflags, implicit killed $r14, debug-location !21
178 renamable $ebx = CMOV32rr renamable $ebx, renamable $edi, 12, implicit killed $eflags, implicit killed $rbx, implicit-def $rbx, debug-location !21
179 renamable $ecx = nsw IMUL32rr renamable $ecx, renamable $ebx, implicit-def dead $eflags, implicit killed $rbx, implicit killed $rcx, implicit-def $rcx, debug-location !21
180 DBG_VALUE $rsp, $noreg, !19, !DIExpression(DW_OP_plus_uconst, 12, DW_OP_deref), debug-location !21
181 DBG_VALUE $ecx, $noreg, !20, !DIExpression(), debug-location !21
182 $esi = MOV32ri 4, debug-location !21
183 renamable $ecx = MOV32rm $rsp, 1, $noreg, 8, $noreg, implicit-def $rcx, debug-location !21 :: (dereferenceable load 4 from %ir.arg3.addr)
184 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
185 DBG_VALUE $eax, $noreg, !14, !DIExpression(), debug-location !21
186 renamable $eax = nsw ADD32ri8 killed renamable $eax, 4, implicit-def dead $eflags, debug-location !21
187 $rsp = frame-destroy ADD64ri8 $rsp, 16, implicit-def dead $eflags, debug-location !21
188 CFI_INSTRUCTION def_cfa_offset 32, debug-location !21
189 $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !21
190 CFI_INSTRUCTION def_cfa_offset 24, debug-location !21
191 $r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !21
192 DBG_VALUE $ecx, $noreg, !17, !DIExpression(DW_OP_entry_value, 1), debug-location !21
193 CFI_INSTRUCTION def_cfa_offset 16, debug-location !21
194 $r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !21
195 DBG_VALUE $esi, $noreg, !15, !DIExpression(DW_OP_entry_value, 1), debug-location !21
196 CFI_INSTRUCTION def_cfa_offset 8, debug-location !21
197 RETQ $eax, debug-location !21
198
199 ...
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_lit8, DW_OP_plus)
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_lit8, DW_OP_plus)
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_lit4, DW_OP_plus)
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_TAG_GNU_call_site_parameter
16 # CHECK-NEXT: DW_AT_location (DW_OP_reg2 RCX)
17 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit15)
18 # CHECK: DW_TAG_GNU_call_site_parameter
19 # CHECK-NEXT: DW_AT_location (DW_OP_reg1 RDX)
20 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_lit10)
21 # CHECK: DW_TAG_GNU_call_site_parameter
22 # CHECK-NEXT: DW_AT_location (DW_OP_reg4 RSI)
23 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg3 RBX+0)
24 # CHECK: DW_TAG_GNU_call_site_parameter
25 # CHECK-NEXT: DW_AT_location (DW_OP_reg5 RDI)
26 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_fbreg +12)
27 # CHECK: DW_TAG_GNU_call_site_parameter
28 # CHECK-NEXT: DW_AT_location (DW_OP_reg9 R9)
29 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg15 R15+0, DW_OP_breg3 RBX+0, DW_OP_plus)
30 # CHECK: DW_TAG_GNU_call_site_parameter
31 # CHECK-NEXT: DW_AT_location (DW_OP_reg8 R8)
32 # CHECK-NEXT: DW_AT_GNU_call_site_value (DW_OP_breg14 R14+3)
33
34 --- |
35 ; ModuleID = 'test.c'
36 source_filename = "test.c"
37 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
38 target triple = "x86_64-unknown-linux-gnu"
39
40 ; Function Attrs: nounwind uwtable
41 define dso_local void @baa(i32 %arg1, i32 %arg2, i32 %arg3) local_unnamed_addr !dbg !10 {
42 entry:
43 %local1 = alloca i32, align 4
44 call void @llvm.dbg.value(metadata i32 %arg1, metadata !15, metadata !DIExpression()), !dbg !19
45 call void @llvm.dbg.value(metadata i32 %arg2, metadata !16, metadata !DIExpression()), !dbg !20
46 call void @llvm.dbg.value(metadata i32 %arg3, metadata !17, metadata !DIExpression()), !dbg !21
47 %0 = bitcast i32* %local1 to i8*, !dbg !22
48 %call = tail call i32 (...) @getVal(), !dbg !23
49 call void @llvm.dbg.value(metadata i32 %call, metadata !18, metadata !DIExpression()), !dbg !24
50 store i32 %call, i32* %local1, align 4, !dbg !24
51 %add = add nsw i32 %arg3, 3, !dbg !24
52 %add1 = add nsw i32 %arg2, %arg1, !dbg !24
53 call void @llvm.dbg.value(metadata i32* %local1, metadata !18, metadata !DIExpression(DW_OP_deref)), !dbg !24
54 call void @foo(i32* nonnull %local1, i32 %arg2, i32 10, i32 15, i32 %add, i32 %add1), !dbg !24
55 ret void, !dbg !24
56 }
57
58 declare !dbg !4 dso_local i32 @getVal(...) local_unnamed_addr
59
60 declare !dbg !5 dso_local void @foo(i32*, i32, i32, i32, i32, i32) local_unnamed_addr
61
62 ; Function Attrs: nounwind readnone speculatable
63 declare void @llvm.dbg.value(metadata, metadata, metadata)
64
65 !llvm.dbg.cu = !{!0}
66 !llvm.module.flags = !{!6, !7, !8}
67 !llvm.ident = !{!9}
68
69 !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)
70 !1 = !DIFile(filename: "test.c", directory: "/dir")
71 !2 = !{}
72 !3 = !{!4, !5}
73 !4 = !DISubprogram(name: "getVal", scope: !1, file: !1, line: 2, spFlags: DISPFlagOptimized, retainedNodes: !2)
74 !5 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
75 !6 = !{i32 2, !"Dwarf Version", i32 4}
76 !7 = !{i32 2, !"Debug Info Version", i32 3}
77 !8 = !{i32 1, !"wchar_size", i32 4}
78 !9 = !{!"clang version 9.0.0"}
79 !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)
80 !11 = !DISubroutineType(types: !12)
81 !12 = !{null, !13, !13, !13}
82 !13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
83 !14 = !{!15, !16, !17, !18}
84 !15 = !DILocalVariable(name: "arg1", arg: 1, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
85 !16 = !DILocalVariable(name: "arg2", arg: 2, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
86 !17 = !DILocalVariable(name: "arg3", arg: 3, scope: !10, file: !1, line: 4, type: !13, flags: DIFlagArgumentNotModified)
87 !18 = !DILocalVariable(name: "local1", scope: !10, file: !1, line: 5, type: !13)
88 !19 = !DILocation(line: 4, column: 14, scope: !10)
89 !20 = !DILocation(line: 4, column: 24, scope: !10)
90 !21 = !DILocation(line: 4, column: 34, scope: !10)
91 !22 = !DILocation(line: 5, column: 3, scope: !10)
92 !23 = !DILocation(line: 5, column: 16, scope: !10)
93 !24 = !DILocation(line: 5, column: 7, scope: !10)
94
95 ...
96 ---
97 name: baa
98 liveins:
99 - { reg: '$edi', virtual-reg: '' }
100 - { reg: '$esi', virtual-reg: '' }
101 - { reg: '$edx', virtual-reg: '' }
102 callSites:
103 - { bb: 0, offset: 21, fwdArgRegs: [] }
104 - { bb: 0, offset: 31, fwdArgRegs:
105 - { arg: 0, reg: '$rdi' }
106 - { arg: 1, reg: '$esi' }
107 - { arg: 2, reg: '$edx' }
108 - { arg: 3, reg: '$ecx' }
109 - { arg: 4, reg: '$r8d' }
110 - { arg: 5, reg: '$r9d' } }
111 body: |
112 bb.0.entry:
113 liveins: $edi, $edx, $esi, $r15, $r14, $rbx
114
115 DBG_VALUE $edi, $noreg, !15, !DIExpression(), debug-location !19
116 DBG_VALUE $esi, $noreg, !16, !DIExpression(), debug-location !20
117 DBG_VALUE $edx, $noreg, !17, !DIExpression(), debug-location !21
118 frame-setup PUSH64r killed $r15, implicit-def $rsp, implicit $rsp
119 CFI_INSTRUCTION def_cfa_offset 16
120 frame-setup PUSH64r killed $r14, implicit-def $rsp, implicit $rsp
121 CFI_INSTRUCTION def_cfa_offset 24
122 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
123 CFI_INSTRUCTION def_cfa_offset 32
124 $rsp = frame-setup SUB64ri8 $rsp, 16, implicit-def dead $eflags
125 CFI_INSTRUCTION def_cfa_offset 48
126 CFI_INSTRUCTION offset $rbx, -32
127 CFI_INSTRUCTION offset $r14, -24
128 CFI_INSTRUCTION offset $r15, -16
129 $r14d = MOV32rr $edx, implicit-def $r14
130 $ebx = MOV32rr $esi, implicit-def $rbx
131 $r15d = MOV32rr $edi, implicit-def $r15
132 DBG_VALUE $r14d, $noreg, !17, !DIExpression(), debug-location !21
133 DBG_VALUE $ebx, $noreg, !16, !DIExpression(), debug-location !20
134 DBG_VALUE $r15d, $noreg, !15, !DIExpression(), debug-location !19
135 dead $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, implicit-def $al, debug-location !23
136 CALL64pcrel32 @getVal, csr_64, implicit $rsp, implicit $ssp, implicit $al, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !23
137 DBG_VALUE $eax, $noreg, !18, !DIExpression(), debug-location !24
138 MOV32mr $rsp, 1, $noreg, 12, $noreg, killed renamable $eax, debug-location !24 :: (store 4 into %ir.local1)
139 renamable $r8d = LEA64_32r killed renamable $r14, 1, $noreg, 3, $noreg, debug-location !24
140 renamable $r9d = LEA64_32r killed renamable $r15, 1, renamable $rbx, 0, $noreg, debug-location !24
141 DBG_VALUE $rsp, $noreg, !18, !DIExpression(DW_OP_plus_uconst, 12, DW_OP_deref), debug-location !24
142 renamable $rdi = LEA64r $rsp, 1, $noreg, 12, $noreg
143 $esi = MOV32rr $ebx, implicit killed $rbx, debug-location !24
144 $edx = MOV32ri 10, debug-location !24
145 $ecx = MOV32ri 15, debug-location !24
146 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
147 $rsp = frame-destroy ADD64ri8 $rsp, 16, implicit-def dead $eflags, debug-location !24
148 CFI_INSTRUCTION def_cfa_offset 32, debug-location !24
149 $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !24
150 CFI_INSTRUCTION def_cfa_offset 24, debug-location !24
151 $r14 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !24
152 CFI_INSTRUCTION def_cfa_offset 16, debug-location !24
153 $r15 = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !24
154 CFI_INSTRUCTION def_cfa_offset 8, debug-location !24
155 RETQ debug-location !24
156
157 ...
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);