Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -267,6 +267,10 @@ /// Tracks dbg_value and dbg_label information through SDISel. SDDbgInfo *DbgInfo; + using CallSiteInfo = MachineFunction::CallSiteInfo; + using CallSiteInfoImpl = MachineFunction::CallSiteInfoImpl; + DenseMap SDCallSiteInfo; + uint16_t NextPersistentId = 0; public: @@ -1619,6 +1623,17 @@ isConstantFPBuildVectorOrConstantFP(N); } + void addCallSiteInfo(const SDNode *CallNode, CallSiteInfoImpl &&CallInfo) { + SDCallSiteInfo[CallNode] = std::move(CallInfo); + } + + CallSiteInfo getSDCallSiteInfo(const SDNode *CallNode) { + auto I = SDCallSiteInfo.find(CallNode); + if (I != SDCallSiteInfo.end()) + return std::move(I->second); + return CallSiteInfo(); + } + private: void InsertNode(SDNode *N); bool RemoveNodeFromCSEMaps(SDNode *N); Index: lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -853,14 +853,20 @@ if (Before == After) return nullptr; + MachineInstr *MI; if (Before == BB->end()) { // There were no prior instructions; the new ones must start at the // beginning of the block. - return &Emitter.getBlock()->instr_front(); + MI = &Emitter.getBlock()->instr_front(); } else { // Return first instruction after the pre-existing instructions. - return &*std::next(Before); + MI = &*std::next(Before); } + + if (MI->isCall() && DAG->getTarget().Options.EnableDebugEntryValues) + MF.addCallArgsForwardingRegs(MI, DAG->getSDCallSiteInfo(Node)); + + return MI; }; // If this is the first BB, emit byval parameter dbg_value's. Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -3586,6 +3586,8 @@ const Module *M = MF.getMMI().getModule(); Metadata *IsCFProtectionSupported = M->getModuleFlag("cf-protection-branch"); + MachineFunction::CallSiteInfo CSInfo; + if (CallConv == CallingConv::X86_INTR) report_fatal_error("X86 interrupts may not be called directly"); @@ -3781,6 +3783,9 @@ Subtarget); } else if (VA.isRegLoc()) { RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); + const TargetOptions &Options = DAG.getTarget().Options; + if (Options.EnableParamEntryValues) + CSInfo.emplace_back(I, VA.getLocReg()); if (isVarArg && IsWin64) { // Win64 ABI requires argument XMM reg to be copied to the corresponding // shadow reg if callee is a varargs function. @@ -4081,7 +4086,9 @@ // should be computed from returns not tail calls. Consider a void // function making a tail call to a function returning int. MF.getFrameInfo().setHasTailCall(); - return DAG.getNode(X86ISD::TC_RETURN, dl, NodeTys, Ops); + SDValue Ret = DAG.getNode(X86ISD::TC_RETURN, dl, NodeTys, Ops); + DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo)); + return Ret; } if (HasNoCfCheck && IsCFProtectionSupported) { @@ -4090,6 +4097,7 @@ Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops); } InFlag = Chain.getValue(1); + DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo)); // Create the CALLSEQ_END node. unsigned NumBytesForCalleeToPop; Index: test/CodeGen/X86/call-site-info-output.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/call-site-info-output.ll @@ -0,0 +1,37 @@ +; Test call site info MIR printer and parser.Parser assertions and machine +; verifier will check the rest; +; RUN: llc -debug-entry-values %s -stop-before=expand-isel-pseudos -o %t.mir +; RUN: cat %t.mir | FileCheck %s +; CHECK: name: fn2 +; CHECK: callSites: +; There is no need to verify call instruction location since it will be +; checked by the MIR parser in the next RUN. +; CHECK-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs: +; CHECK-NEXT: arg: 0, reg: '$edi' +; CHECK-NEXT: arg: 1, reg: '$esi' +; CHECK-NEXT: arg: 2, reg: '$edx' +; RUN: llc -debug-entry-values %t.mir -start-before=expand-isel-pseudos -o - + +; ModuleID = 'test/CodeGen/X86/call-site-info-output.c' +source_filename = "test/CodeGen/X86/call-site-info-output.c" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noinline nounwind uwtable +define dso_local i64 @fn2(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 { +entry: + %call = tail call i32 (i32, i32, i32, ...) bitcast (i32 (...)* @fn1 to i32 (i32, i32, i32, ...)*)(i32 -50, i32 50, i32 -7) #2 + %add = mul i32 %a, 3 + %sub = sub i32 %add, %b + %add2 = add i32 %sub, %c + %conv4 = sext i32 %add2 to i64 + ret i64 %conv4 +} + +declare dso_local i32 @fn1(...) local_unnamed_addr #1 + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 9.0.0"}