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
This commit is contained in:
Chris Lattner 2006-06-10 01:14:28 +00:00
parent deafba0325
commit 006b2c6ab9
2 changed files with 22 additions and 18 deletions

View File

@ -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();

View File

@ -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)]>;
}