aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-06-10 01:14:28 +0000
committerChris Lattner <sabre@nondot.org>2006-06-10 01:14:28 +0000
commit4a45abf66ee33ce3b8404ace90c4bfefda7105f8 (patch)
tree7ec6a64c561a7e4a4f3bf5a8a76ff77503a3ab53
parent11bcd28dfff6868a37dc49fc6f322094874e3967 (diff)
Fix a problem exposed by the local allocator. CALL instructions are not marked
as using incoming argument registers, so the local allocator would clobber them between their set and use. To fix this, we give the call instructions a variable number of uses in the CALL MachineInstr itself, so live variables understands the live ranges of these register arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28744 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp32
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td8
2 files changed, 22 insertions, 18 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index a021c0e2d7..03e0d38d10 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1041,6 +1041,11 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
}
std::vector<MVT::ValueType> NodeTys;
+ NodeTys.push_back(MVT::Other); // Returns a chain
+ NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
+
+ std::vector<SDOperand> Ops;
+ unsigned CallOpc = PPCISD::CALL;
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
@@ -1055,11 +1060,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
else {
// Otherwise, this is an indirect call. We have to use a MTCTR/BCTRL pair
// to do the call, we can't use PPCISD::CALL.
- std::vector<SDOperand> Ops;
Ops.push_back(Chain);
Ops.push_back(Callee);
- NodeTys.push_back(MVT::Other);
- NodeTys.push_back(MVT::Flag);
if (InFlag.Val)
Ops.push_back(InFlag);
@@ -1075,25 +1077,27 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
NodeTys.push_back(MVT::Flag);
Ops.clear();
Ops.push_back(Chain);
- Ops.push_back(InFlag);
- Chain = DAG.getNode(PPCISD::BCTRL, NodeTys, Ops);
- InFlag = Chain.getValue(1);
+ CallOpc = PPCISD::BCTRL;
Callee.Val = 0;
}
- // Create the PPCISD::CALL node itself.
+ // If this is a direct call, pass the chain and the callee.
if (Callee.Val) {
- NodeTys.push_back(MVT::Other); // Returns a chain
- NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
- std::vector<SDOperand> Ops;
Ops.push_back(Chain);
Ops.push_back(Callee);
- if (InFlag.Val)
- Ops.push_back(InFlag);
- Chain = DAG.getNode(PPCISD::CALL, NodeTys, Ops);
- InFlag = Chain.getValue(1);
}
+ // Add argument registers to the end of the list so that they are known live
+ // into the call.
+ for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
+ Ops.push_back(DAG.getRegister(RegsToPass[i].first,
+ RegsToPass[i].second.getValueType()));
+
+ if (InFlag.Val)
+ Ops.push_back(InFlag);
+ Chain = DAG.getNode(CallOpc, NodeTys, Ops);
+ InFlag = Chain.getValue(1);
+
std::vector<SDOperand> ResultVals;
NodeTys.clear();
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index c93e0d4d83..460826b314 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -71,7 +71,7 @@ def PPCstd_32 : SDNode<"PPCISD::STD_32" , SDTStore, [SDNPHasChain]>;
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeq,[SDNPHasChain]>;
-def SDT_PPCCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall,
@@ -310,11 +310,11 @@ let isCall = 1, noResults = 1, PPC970_Unit = 7,
LR,CTR,
CR0,CR1,CR5,CR6,CR7] in {
// Convenient aliases for call instructions
- def BL : IForm<18, 0, 1, (ops calltarget:$func),
+ def BL : IForm<18, 0, 1, (ops calltarget:$func, variable_ops),
"bl $func", BrB, []>; // See Pat patterns below.
- def BLA : IForm<18, 1, 1, (ops aaddr:$func),
+ def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
"bla $func", BrB, [(PPCcall imm:$func)]>;
- def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops), "bctrl", BrB,
+ def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB,
[(PPCbctrl)]>;
}