From f838cfcfbe171675b61368b23f9587f28589fd6a Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 20 May 2006 01:36:52 +0000 Subject: [PATCH] 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. llvm-svn: 28416 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 58 +++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 40b69dcec374..3cf36a5394bc 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -516,6 +516,13 @@ SDOperand X86DAGToDAGISel::getGlobalBaseReg() { 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) { SDNode *Node = N.Val; MVT::ValueType NVT = Node->getValueType(0); @@ -826,6 +833,57 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) { 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);