/// Tracks dbg_value and dbg_label information through SDISel.
SDDbgInfo *DbgInfo;
+ using CallSiteInfo = MachineFunction::CallSiteInfo;
+ using CallSiteInfoImpl = MachineFunction::CallSiteInfoImpl;
+ DenseMap<const SDNode *, CallSiteInfo> SDCallSiteInfo;
+
uint16_t NextPersistentId = 0;
public:
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);
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.
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");
Subtarget);
} else if (VA.isRegLoc()) {
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
+ const TargetOptions &Options = DAG.getTarget().Options;
+ if (Options.EnableDebugEntryValues)
+ CSInfo.emplace_back(VA.getLocReg(), I);
if (isVarArg && IsWin64) {
// Win64 ABI requires argument XMM reg to be copied to the corresponding
// shadow reg if callee is a varargs function.
// 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) {
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;
--- /dev/null
+; 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=finalize-isel -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 -run-pass=finalize-isel -o -| FileCheck %s --check-prefix=PARSER
+; Verify that we are able to parse output mir and that we are getting the same result.
+; PARSER: name: fn2
+; PARSER: callSites:
+; PARSER-NEXT: bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; PARSER-NEXT: arg: 0, reg: '$edi'
+; PARSER-NEXT: arg: 1, reg: '$esi'
+; PARSER-NEXT: arg: 2, reg: '$edx'
+
+; 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 {
+entry:
+ %call = tail call i32 (i32, i32, i32, ...) bitcast (i32 (...)* @fn1 to i32 (i32, i32, i32, ...)*)(i32 -50, i32 50, i32 -7)
+ %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
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 9.0.0"}