llvm.org GIT mirror llvm / fc52163
Support nested CALLSEQ_BEGIN/END; necessary for ARM byval support. <rdar://problem/7662569> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129761 91177308-0d34-0410-b5e6-96231b3b80d8 Stuart Hastings 9 years ago
1 changed file(s) with 57 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
6060
6161 // Libcall insertion helpers.
6262
63 /// LastCALLSEQ_END - This keeps track of the CALLSEQ_END node that has been
63 /// LastCALLSEQ - This keeps track of the CALLSEQ_END node that has been
6464 /// legalized. We use this to ensure that calls are properly serialized
6565 /// against each other, including inserted libcalls.
66 SDValue LastCALLSEQ_END;
67
68 /// IsLegalizingCall - This member is used *only* for purposes of providing
69 /// helpful assertions that a libcall isn't created while another call is
70 /// being legalized (which could lead to non-serialized call sequences).
71 bool IsLegalizingCall;
66 SmallVector LastCALLSEQ;
67
68 // Track CALLSEQ_BEGIN/CALLSEQ_END nesting.
69 int depthCALLSEQ;
7270
7371 enum LegalizeAction {
7472 Legal, // The target natively supports this operation.
183181
184182 void ExpandNode(SDNode *Node, SmallVectorImpl &Results);
185183 void PromoteNode(SDNode *Node, SmallVectorImpl &Results);
184
185 SDValue getLastCALLSEQ() { return LastCALLSEQ.back(); /*[depthCALLSEQ];*/ }
186 void setLastCALLSEQ(const SDValue s) { LastCALLSEQ.back() /*[depthCALLSEQ]*/ = s; }
187 void pushLastCALLSEQ(SDValue s) {
188 depthCALLSEQ++;
189 LastCALLSEQ.push_back(s);
190 }
191 void popLastCALLSEQ() {
192 LastCALLSEQ.pop_back();
193 depthCALLSEQ--;
194 assert(depthCALLSEQ >= 0 && "excess pop of LastCALLSEQ");
195 }
186196 };
187197 }
188198
228238 }
229239
230240 void SelectionDAGLegalize::LegalizeDAG() {
231 LastCALLSEQ_END = DAG.getEntryNode();
232 IsLegalizingCall = false;
241 depthCALLSEQ = 0;
242 pushLastCALLSEQ(DAG.getEntryNode());
233243
234244 // The legalize process is inherently a bottom-up recursive process (users
235245 // legalize their uses before themselves). Given infinite stack space, we
257267 /// FindCallEndFromCallStart - Given a chained node that is part of a call
258268 /// sequence, find the CALLSEQ_END node that terminates the call sequence.
259269 static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) {
260 // Nested CALLSEQ_START/END constructs aren't yet legal,
261 // but we can DTRT and handle them correctly here.
270 int next_depth = depth;
262271 if (Node->getOpcode() == ISD::CALLSEQ_START)
263 depth++;
264 else if (Node->getOpcode() == ISD::CALLSEQ_END) {
265 depth--;
266 if (depth == 0)
272 next_depth = depth + 1;
273 if (Node->getOpcode() == ISD::CALLSEQ_END) {
274 assert(depth > 0 && "negative depth!");
275 if (depth == 1)
267276 return Node;
277 else
278 next_depth = depth - 1;
268279 }
269280 if (Node->use_empty())
270281 return 0; // No CallSeqEnd
295306 SDNode *User = *UI;
296307 for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
297308 if (User->getOperand(i) == TheChain)
298 if (SDNode *Result = FindCallEndFromCallStart(User, depth))
309 if (SDNode *Result = FindCallEndFromCallStart(User, next_depth))
299310 return Result;
300311 }
301312 return 0;
940951 case ISD::BR_JT:
941952 case ISD::BR_CC:
942953 case ISD::BRCOND:
943 // Branches tweak the chain to include LastCALLSEQ_END
954 assert(depthCALLSEQ == 1 && "branch inside CALLSEQ_BEGIN/END?");
955 // Branches tweak the chain to include LastCALLSEQ
944956 Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0],
945 LastCALLSEQ_END);
957 getLastCALLSEQ());
946958 Ops[0] = LegalizeOp(Ops[0]);
947 LastCALLSEQ_END = DAG.getEntryNode();
959 setLastCALLSEQ(DAG.getEntryNode());
948960 break;
949961 case ISD::SHL:
950962 case ISD::SRL:
10331045 break;
10341046 case ISD::CALLSEQ_START: {
10351047 SDNode *CallEnd = FindCallEndFromCallStart(Node);
1048 assert(CallEnd && "didn't find CALLSEQ_END!");
10361049
10371050 // Recursively Legalize all of the inputs of the call end that do not lead
10381051 // to this call start. This ensures that any libcalls that need be inserted
10491062
10501063 // Merge in the last call to ensure that this call starts after the last
10511064 // call ended.
1052 if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) {
1065 if (getLastCALLSEQ().getOpcode() != ISD::EntryToken) {
10531066 Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
1054 Tmp1, LastCALLSEQ_END);
1067 Tmp1, getLastCALLSEQ());
10551068 Tmp1 = LegalizeOp(Tmp1);
10561069 }
10571070
10721085 // sequence have been legalized, legalize the call itself. During this
10731086 // process, no libcalls can/will be inserted, guaranteeing that no calls
10741087 // can overlap.
1075 assert(!IsLegalizingCall && "Inconsistent sequentialization of calls!");
10761088 // Note that we are selecting this call!
1077 LastCALLSEQ_END = SDValue(CallEnd, 0);
1078 IsLegalizingCall = true;
1089 setLastCALLSEQ(SDValue(CallEnd, 0));
10791090
10801091 // Legalize the call, starting from the CALLSEQ_END.
1081 LegalizeOp(LastCALLSEQ_END);
1082 assert(!IsLegalizingCall && "CALLSEQ_END should have cleared this!");
1092 LegalizeOp(getLastCALLSEQ());
10831093 return Result;
10841094 }
10851095 case ISD::CALLSEQ_END:
1086 // If the CALLSEQ_START node hasn't been legalized first, legalize it. This
1087 // will cause this node to be legalized as well as handling libcalls right.
1088 if (LastCALLSEQ_END.getNode() != Node) {
1089 LegalizeOp(SDValue(FindCallStartFromCallEnd(Node), 0));
1090 DenseMap::iterator I = LegalizedNodes.find(Op);
1091 assert(I != LegalizedNodes.end() &&
1092 "Legalizing the call start should have legalized this node!");
1093 return I->second;
1096 {
1097 SDNode *myCALLSEQ_BEGIN = FindCallStartFromCallEnd(Node);
1098
1099 // If the CALLSEQ_START node hasn't been legalized first, legalize it. This
1100 // will cause this node to be legalized as well as handling libcalls right.
1101 if (getLastCALLSEQ().getNode() != Node) {
1102 LegalizeOp(SDValue(myCALLSEQ_BEGIN, 0));
1103 DenseMap::iterator I = LegalizedNodes.find(Op);
1104 assert(I != LegalizedNodes.end() &&
1105 "Legalizing the call start should have legalized this node!");
1106 return I->second;
1107 }
1108
1109 pushLastCALLSEQ(SDValue(myCALLSEQ_BEGIN, 0));
10941110 }
10951111
10961112 // Otherwise, the call start has been legalized and everything is going
11181134 Result.getResNo());
11191135 }
11201136 }
1121 assert(IsLegalizingCall && "Call sequence imbalance between start/end?");
11221137 // This finishes up call legalization.
1123 IsLegalizingCall = false;
1138 popLastCALLSEQ();
11241139
11251140 // If the CALLSEQ_END node has a flag, remember that we legalized it.
11261141 AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
20062021 // and leave the Hi part unset.
20072022 SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
20082023 bool isSigned) {
2009 assert(!IsLegalizingCall && "Cannot overlap legalization of calls!");
20102024 // The input chain to this libcall is the entry node of the function.
20112025 // Legalizing the call will automatically add the previous call to the
20122026 // dependence.
20422056 return DAG.getRoot();
20432057
20442058 // Legalize the call sequence, starting with the chain. This will advance
2045 // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
2059 // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that
20462060 // was added by LowerCallTo (guaranteeing proper serialization of calls).
20472061 LegalizeOp(CallInfo.second);
20482062 return CallInfo.first;
20542068 SelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC,
20552069 SDNode *Node,
20562070 bool isSigned) {
2057 assert(!IsLegalizingCall && "Cannot overlap legalization of calls!");
20582071 SDValue InChain = Node->getOperand(0);
20592072
20602073 TargetLowering::ArgListTy Args;
20802093 Callee, Args, DAG, Node->getDebugLoc());
20812094
20822095 // Legalize the call sequence, starting with the chain. This will advance
2083 // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
2096 // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that
20842097 // was added by LowerCallTo (guaranteeing proper serialization of calls).
20852098 LegalizeOp(CallInfo.second);
20862099 return CallInfo;
22162229 /*isReturnValueUsed=*/true, Callee, Args, DAG, dl);
22172230
22182231 // Legalize the call sequence, starting with the chain. This will advance
2219 // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
2232 // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that
22202233 // was added by LowerCallTo (guaranteeing proper serialization of calls).
22212234 LegalizeOp(CallInfo.second);
22222235
22232236 // Remainder is loaded back from the stack frame.
2224 SDValue Rem = DAG.getLoad(RetVT, dl, LastCALLSEQ_END, FIPtr,
2237 SDValue Rem = DAG.getLoad(RetVT, dl, getLastCALLSEQ(), FIPtr,
22252238 MachinePointerInfo(), false, false, 0);
22262239 Results.push_back(CallInfo.first);
22272240 Results.push_back(Rem);
35323545
35333546 LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp2.getValueType()),
35343547 Tmp2, Tmp3, Tmp4, dl);
3535 LastCALLSEQ_END = DAG.getEntryNode();
3548 assert(depthCALLSEQ == 1 && "branch inside CALLSEQ_BEGIN/END?");
3549 setLastCALLSEQ(DAG.getEntryNode());
35363550
35373551 assert(!Tmp3.getNode() && "Can't legalize BR_CC with legal condition!");
35383552 Tmp3 = DAG.getConstant(0, Tmp2.getValueType());