summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikola Prica <nikola.prica@rt-rk.com>2019-10-08 09:43:05 +0000
committerNikola Prica <nikola.prica@rt-rk.com>2019-10-08 09:43:05 +0000
commit02682498b86a72a53415a3676042b1a7d30ccbdc (patch)
tree0fa42f3b3276e39cc9ad612b498dd57ff82838f8
parentfb190c82983589eedfde7d1424c350eeb3d00050 (diff)
downloadbcm5719-llvm-02682498b86a72a53415a3676042b1a7d30ccbdc.tar.gz
bcm5719-llvm-02682498b86a72a53415a3676042b1a7d30ccbdc.zip
[ISEL][ARM][AARCH64] Tracking simple parameter forwarding registers
Support for tracking registers that forward function parameters into the following function frame. For now we only support cases when parameter is forwarded through single register. Reviewers: aprantl, vsk, t.p.northover Reviewed By: vsk Differential Revision: https://reviews.llvm.org/D66953 llvm-svn: 374033
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp17
-rw-r--r--llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp6
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp9
-rw-r--r--llvm/test/DebugInfo/AArch64/call-site-info-output.ll41
-rw-r--r--llvm/test/DebugInfo/ARM/call-site-info-output.ll41
5 files changed, 111 insertions, 3 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index bec14001ed8..c7302b45f65 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3692,6 +3692,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
bool IsVarArg = CLI.IsVarArg;
MachineFunction &MF = DAG.getMachineFunction();
+ MachineFunction::CallSiteInfo CSInfo;
bool IsThisReturn = false;
AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
@@ -3889,9 +3890,20 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
})
->second;
Bits = DAG.getNode(ISD::OR, DL, Bits.getValueType(), Bits, Arg);
+ // Call site info is used for function's parameter entry value
+ // tracking. For now we track only simple cases when parameter
+ // is transferred through whole register.
+ CSInfo.erase(std::remove_if(CSInfo.begin(), CSInfo.end(),
+ [&VA](MachineFunction::ArgRegPair ArgReg) {
+ return ArgReg.Reg == VA.getLocReg();
+ }),
+ CSInfo.end());
} else {
RegsToPass.emplace_back(VA.getLocReg(), Arg);
RegsUsed.insert(VA.getLocReg());
+ const TargetOptions &Options = DAG.getTarget().Options;
+ if (Options.EnableDebugEntryValues)
+ CSInfo.emplace_back(VA.getLocReg(), i);
}
} else {
assert(VA.isMemLoc());
@@ -4072,12 +4084,15 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// actual call instruction.
if (IsTailCall) {
MF.getFrameInfo().setHasTailCall();
- return DAG.getNode(AArch64ISD::TC_RETURN, DL, NodeTys, Ops);
+ SDValue Ret = DAG.getNode(AArch64ISD::TC_RETURN, DL, NodeTys, Ops);
+ DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
+ return Ret;
}
// Returns a chain and a flag for retval copy to use.
Chain = DAG.getNode(AArch64ISD::CALL, DL, NodeTys, Ops);
InFlag = Chain.getValue(1);
+ DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
uint64_t CalleePopBytes =
DoesCalleeRestoreStack(CallConv, TailCallOpt) ? alignTo(NumBytes, 16) : 0;
diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index 73ebe0940f3..3724c0fd265 100644
--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -1205,8 +1205,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
for (unsigned i = 1, e = MBBI->getNumOperands(); i != e; ++i)
NewMI->addOperand(MBBI->getOperand(i));
- // Delete the pseudo instruction TCRETURN.
+
+ // Update call site info and delete the pseudo instruction TCRETURN.
+ MBB.getParent()->updateCallSiteInfo(&MI, &*NewMI);
MBB.erase(MBBI);
+
MBBI = NewMI;
return true;
}
@@ -1436,6 +1439,7 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
MIB.cloneMemRefs(MI);
TransferImpOps(MI, MIB, MIB);
+ MI.getMF()->updateCallSiteInfo(&MI, &*MIB);
MI.eraseFromParent();
return true;
}
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index ec553708798..c1365f58930 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2040,6 +2040,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
bool isVarArg = CLI.IsVarArg;
MachineFunction &MF = DAG.getMachineFunction();
+ MachineFunction::CallSiteInfo CSInfo;
bool isStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
bool isThisReturn = false;
auto Attr = MF.getFunction().getFnAttribute("disable-tail-calls");
@@ -2164,6 +2165,9 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
"unexpected use of 'returned'");
isThisReturn = true;
}
+ const TargetOptions &Options = DAG.getTarget().Options;
+ if (Options.EnableDebugEntryValues)
+ CSInfo.emplace_back(VA.getLocReg(), i);
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
} else if (isByVal) {
assert(VA.isMemLoc());
@@ -2399,12 +2403,15 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
if (isTailCall) {
MF.getFrameInfo().setHasTailCall();
- return DAG.getNode(ARMISD::TC_RETURN, dl, NodeTys, Ops);
+ SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, NodeTys, Ops);
+ DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
+ return Ret;
}
// Returns a chain and a flag for retval copy to use.
Chain = DAG.getNode(CallOpc, dl, NodeTys, Ops);
InFlag = Chain.getValue(1);
+ DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, dl, true),
DAG.getIntPtrConstant(0, dl, true), InFlag, dl);
diff --git a/llvm/test/DebugInfo/AArch64/call-site-info-output.ll b/llvm/test/DebugInfo/AArch64/call-site-info-output.ll
new file mode 100644
index 00000000000..d52d6962f3c
--- /dev/null
+++ b/llvm/test/DebugInfo/AArch64/call-site-info-output.ll
@@ -0,0 +1,41 @@
+; RUN: llc -mtriple aarch64-linux-gnu -debug-entry-values %s -o - -stop-before=finalize-isel | FileCheck %s
+; Verify that Selection DAG knows how to recognize simple function parameter forwarding registers.
+; Produced from:
+; extern int fn1(int,int,int);
+; int fn2(int a, int b, int c) {
+; int local = fn1(a+b, c, 10);
+; if (local > 10)
+; return local + 10;
+; return local;
+; }
+; clang -g -O2 -target aarch64-linux-gnu -S -emit-llvm %s
+; CHECK: callSites:
+; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; CHECK-NEXT: - { arg: 0, reg: '$w0' }
+; CHECK-NEXT: - { arg: 1, reg: '$w1' }
+; CHECK-NEXT: - { arg: 2, reg: '$w2' } }
+
+; ModuleID = 'call-site-info-output.c'
+source_filename = "call-site-info-output.c"
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define dso_local i32 @fn2(i32 %a, i32 %b, i32 %c) local_unnamed_addr{
+entry:
+ %add = add nsw i32 %b, %a
+ %call = tail call i32 @fn1(i32 %add, i32 %c, i32 10)
+ %cmp = icmp sgt i32 %call, 10
+ %add1 = add nsw i32 %call, 10
+ %retval.0 = select i1 %cmp, i32 %add1, i32 %call
+ ret i32 %retval.0
+}
+
+declare dso_local i32 @fn1(i32, i32, i32) local_unnamed_addr
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 10.0.0"}
diff --git a/llvm/test/DebugInfo/ARM/call-site-info-output.ll b/llvm/test/DebugInfo/ARM/call-site-info-output.ll
new file mode 100644
index 00000000000..9255a7d57dd
--- /dev/null
+++ b/llvm/test/DebugInfo/ARM/call-site-info-output.ll
@@ -0,0 +1,41 @@
+; RUN: llc -mtriple arm-linux-gnu -debug-entry-values %s -o - -stop-before=finalize-isel | FileCheck %s
+; Verify that Selection DAG knows how to recognize simple function parameter forwarding registers.
+; Produced from:
+; extern int fn1(int,int,int);
+; int fn2(int a, int b, int c) {
+; int local = fn1(a+b, c, 10);
+; if (local > 10)
+; return local + 10;
+; return local;
+; }
+; clang -g -O2 -target arm-linux-gnu -S -emit-llvm %s
+; CHECK: callSites:
+; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs:
+; CHECK-NEXT: - { arg: 0, reg: '$r0' }
+; CHECK-NEXT: - { arg: 1, reg: '$r1' }
+; CHECK-NEXT: - { arg: 2, reg: '$r2' } }
+
+; ModuleID = 'call-site-info-output.c'
+source_filename = "call-site-info-output.c"
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv4t-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define dso_local arm_aapcscc i32 @fn2(i32 %a, i32 %b, i32 %c) {
+entry:
+ %add = add nsw i32 %b, %a
+ %call = tail call arm_aapcscc i32 @fn1(i32 %add, i32 %c, i32 10)
+ %cmp = icmp sgt i32 %call, 10
+ %add1 = select i1 %cmp, i32 %c, i32 0
+ %retval.0 = add nsw i32 %add1, %call
+ ret i32 %retval.0
+}
+
+declare dso_local arm_aapcscc i32 @fn1(i32, i32, i32) local_unnamed_addr
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 10.0.0"}
OpenPOWER on IntegriCloud