summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
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
commit006b2c6ab9173940fa59ab50b6224452c0ef388a (patch)
treeae80ed82739c0dcea12ad8aadee09366a2a36e01 /llvm/lib/Target/PowerPC/PPCISelLowering.cpp
parentdeafba032593c2012f097124fe97d0a08b5f6f96 (diff)
downloadbcm5719-llvm-006b2c6ab9173940fa59ab50b6224452c0ef388a.tar.gz
bcm5719-llvm-006b2c6ab9173940fa59ab50b6224452c0ef388a.zip
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. llvm-svn: 28744
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp32
1 files changed, 18 insertions, 14 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index a021c0e2d7f..03e0d38d105 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/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();
OpenPOWER on IntegriCloud