mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-03 17:24:24 +00:00
Handle indirect call which folds a load manually. This never matches by
the TableGen generated code since the load's chain result is read by the callseq_start node. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28416 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8f7f4cc1ae
commit
b245d92328
@ -516,6 +516,13 @@ SDOperand X86DAGToDAGISel::getGlobalBaseReg() {
|
|||||||
return CurDAG->getRegister(GlobalBaseReg, MVT::i32);
|
return CurDAG->getRegister(GlobalBaseReg, MVT::i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDNode *FindCallStartFromCall(SDNode *Node) {
|
||||||
|
if (Node->getOpcode() == ISD::CALLSEQ_START) return Node;
|
||||||
|
assert(Node->getOperand(0).getValueType() == MVT::Other &&
|
||||||
|
"Node doesn't have a token chain argument!");
|
||||||
|
return FindCallStartFromCall(Node->getOperand(0).Val);
|
||||||
|
}
|
||||||
|
|
||||||
void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
||||||
SDNode *Node = N.Val;
|
SDNode *Node = N.Val;
|
||||||
MVT::ValueType NVT = Node->getValueType(0);
|
MVT::ValueType NVT = Node->getValueType(0);
|
||||||
@ -826,6 +833,57 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case X86ISD::CALL: {
|
||||||
|
// Handle indirect call which folds a load here. This never matches by
|
||||||
|
// the TableGen generated code since the load's chain result is read by
|
||||||
|
// the callseq_start node.
|
||||||
|
SDOperand N1 = Node->getOperand(1);
|
||||||
|
if (N1.getOpcode() == ISD::LOAD && N1.hasOneUse() &&
|
||||||
|
!CodeGenMap.count(N1.getValue(0))) {
|
||||||
|
SDOperand Chain = Node->getOperand(0);
|
||||||
|
SDNode *CallStart = FindCallStartFromCall(Chain.Val);
|
||||||
|
if (!CallStart || CallStart->getOperand(0).Val != N1.Val)
|
||||||
|
break;
|
||||||
|
SDOperand Base, Scale, Index, Disp;
|
||||||
|
if (SelectAddr(N1.getOperand(1), Base, Scale, Index, Disp)) {
|
||||||
|
Select(Base, Base);
|
||||||
|
Select(Scale, Scale);
|
||||||
|
Select(Index, Index);
|
||||||
|
Select(Disp, Disp);
|
||||||
|
Select(Chain, Chain);
|
||||||
|
bool HasOptInFlag = false;
|
||||||
|
SDOperand InFlag;
|
||||||
|
if (N.getNumOperands() == 3) {
|
||||||
|
Select(InFlag, N.getOperand(2));
|
||||||
|
HasOptInFlag = true;
|
||||||
|
}
|
||||||
|
SDNode *ResNode;
|
||||||
|
if (HasOptInFlag)
|
||||||
|
ResNode = CurDAG->getTargetNode(X86::CALL32m, MVT::Other, MVT::Flag,
|
||||||
|
Base, Scale, Index, Disp, Chain,
|
||||||
|
InFlag);
|
||||||
|
else
|
||||||
|
ResNode = CurDAG->getTargetNode(X86::CALL32m, MVT::Other, MVT::Flag,
|
||||||
|
Base, Scale, Index, Disp, Chain);
|
||||||
|
|
||||||
|
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val,
|
||||||
|
Chain.ResNo);
|
||||||
|
SelectionDAG::InsertISelMapEntry(CodeGenMap, N1.Val, 1, ResNode, 0);
|
||||||
|
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, ResNode, 1);
|
||||||
|
Result = SDOperand(ResNode, 0);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
||||||
|
DEBUG(std::cerr << "== ");
|
||||||
|
DEBUG(Result.Val->dump(CurDAG));
|
||||||
|
DEBUG(std::cerr << "\n");
|
||||||
|
Indent -= 2;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectCode(Result, N);
|
SelectCode(Result, N);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user