@@ -2467,167 +2467,6 @@ SDValue SelectionDAG::getShiftAmountOperand(EVT LHSTy, SDValue Op) {
24672467 return getZExtOrTrunc(Op, SDLoc(Op), ShTy);
24682468}
24692469
2470- /// Given a store node \p StoreNode, return true if it is safe to fold that node
2471- /// into \p FPNode, which expands to a library call with output pointers.
2472- static bool canFoldStoreIntoLibCallOutputPointers(StoreSDNode *StoreNode,
2473- SDNode *FPNode) {
2474- SmallVector<const SDNode *, 8> Worklist;
2475- SmallVector<const SDNode *, 8> DeferredNodes;
2476- SmallPtrSet<const SDNode *, 16> Visited;
2477-
2478- // Skip FPNode use by StoreNode (that's the use we want to fold into FPNode).
2479- for (SDValue Op : StoreNode->ops())
2480- if (Op.getNode() != FPNode)
2481- Worklist.push_back(Op.getNode());
2482-
2483- unsigned MaxSteps = SelectionDAG::getHasPredecessorMaxSteps();
2484- while (!Worklist.empty()) {
2485- const SDNode *Node = Worklist.pop_back_val();
2486- auto [_, Inserted] = Visited.insert(Node);
2487- if (!Inserted)
2488- continue;
2489-
2490- if (MaxSteps > 0 && Visited.size() >= MaxSteps)
2491- return false;
2492-
2493- // Reached the FPNode (would result in a cycle).
2494- // OR Reached CALLSEQ_START (would result in nested call sequences).
2495- if (Node == FPNode || Node->getOpcode() == ISD::CALLSEQ_START)
2496- return false;
2497-
2498- if (Node->getOpcode() == ISD::CALLSEQ_END) {
2499- // Defer looking into call sequences (so we can check we're outside one).
2500- // We still need to look through these for the predecessor check.
2501- DeferredNodes.push_back(Node);
2502- continue;
2503- }
2504-
2505- for (SDValue Op : Node->ops())
2506- Worklist.push_back(Op.getNode());
2507- }
2508-
2509- // True if we're outside a call sequence and don't have the FPNode as a
2510- // predecessor. No cycles or nested call sequences possible.
2511- return !SDNode::hasPredecessorHelper(FPNode, Visited, DeferredNodes,
2512- MaxSteps);
2513- }
2514-
2515- bool SelectionDAG::expandMultipleResultFPLibCall(
2516- RTLIB::Libcall LC, SDNode *Node, SmallVectorImpl<SDValue> &Results,
2517- std::optional<unsigned> CallRetResNo) {
2518- if (LC == RTLIB::UNKNOWN_LIBCALL)
2519- return false;
2520-
2521- RTLIB::LibcallImpl LibcallImpl = TLI->getLibcallImpl(LC);
2522- if (LibcallImpl == RTLIB::Unsupported)
2523- return false;
2524-
2525- LLVMContext &Ctx = *getContext();
2526- EVT VT = Node->getValueType(0);
2527- unsigned NumResults = Node->getNumValues();
2528-
2529- // Find users of the node that store the results (and share input chains). The
2530- // destination pointers can be used instead of creating stack allocations.
2531- SDValue StoresInChain;
2532- SmallVector<StoreSDNode *, 2> ResultStores(NumResults);
2533- for (SDNode *User : Node->users()) {
2534- if (!ISD::isNormalStore(User))
2535- continue;
2536- auto *ST = cast<StoreSDNode>(User);
2537- SDValue StoreValue = ST->getValue();
2538- unsigned ResNo = StoreValue.getResNo();
2539- // Ensure the store corresponds to an output pointer.
2540- if (CallRetResNo == ResNo)
2541- continue;
2542- // Ensure the store to the default address space and not atomic or volatile.
2543- if (!ST->isSimple() || ST->getAddressSpace() != 0)
2544- continue;
2545- // Ensure all store chains are the same (so they don't alias).
2546- if (StoresInChain && ST->getChain() != StoresInChain)
2547- continue;
2548- // Ensure the store is properly aligned.
2549- Type *StoreType = StoreValue.getValueType().getTypeForEVT(Ctx);
2550- if (ST->getAlign() <
2551- getDataLayout().getABITypeAlign(StoreType->getScalarType()))
2552- continue;
2553- // Avoid:
2554- // 1. Creating cyclic dependencies.
2555- // 2. Expanding the node to a call within a call sequence.
2556- if (!canFoldStoreIntoLibCallOutputPointers(ST, Node))
2557- continue;
2558- ResultStores[ResNo] = ST;
2559- StoresInChain = ST->getChain();
2560- }
2561-
2562- TargetLowering::ArgListTy Args;
2563-
2564- // Pass the arguments.
2565- for (const SDValue &Op : Node->op_values()) {
2566- EVT ArgVT = Op.getValueType();
2567- Type *ArgTy = ArgVT.getTypeForEVT(Ctx);
2568- Args.emplace_back(Op, ArgTy);
2569- }
2570-
2571- // Pass the output pointers.
2572- SmallVector<SDValue, 2> ResultPtrs(NumResults);
2573- Type *PointerTy = PointerType::getUnqual(Ctx);
2574- for (auto [ResNo, ST] : llvm::enumerate(ResultStores)) {
2575- if (ResNo == CallRetResNo)
2576- continue;
2577- EVT ResVT = Node->getValueType(ResNo);
2578- SDValue ResultPtr = ST ? ST->getBasePtr() : CreateStackTemporary(ResVT);
2579- ResultPtrs[ResNo] = ResultPtr;
2580- Args.emplace_back(ResultPtr, PointerTy);
2581- }
2582-
2583- SDLoc DL(Node);
2584-
2585- if (RTLIB::RuntimeLibcallsInfo::hasVectorMaskArgument(LibcallImpl)) {
2586- // Pass the vector mask (if required).
2587- EVT MaskVT = TLI->getSetCCResultType(getDataLayout(), Ctx, VT);
2588- SDValue Mask = getBoolConstant(true, DL, MaskVT, VT);
2589- Args.emplace_back(Mask, MaskVT.getTypeForEVT(Ctx));
2590- }
2591-
2592- Type *RetType = CallRetResNo.has_value()
2593- ? Node->getValueType(*CallRetResNo).getTypeForEVT(Ctx)
2594- : Type::getVoidTy(Ctx);
2595- SDValue InChain = StoresInChain ? StoresInChain : getEntryNode();
2596- SDValue Callee =
2597- getExternalSymbol(TLI->getLibcallImplName(LibcallImpl).data(),
2598- TLI->getPointerTy(getDataLayout()));
2599- TargetLowering::CallLoweringInfo CLI(*this);
2600- CLI.setDebugLoc(DL).setChain(InChain).setLibCallee(
2601- TLI->getLibcallImplCallingConv(LibcallImpl), RetType, Callee,
2602- std::move(Args));
2603-
2604- auto [Call, CallChain] = TLI->LowerCallTo(CLI);
2605-
2606- for (auto [ResNo, ResultPtr] : llvm::enumerate(ResultPtrs)) {
2607- if (ResNo == CallRetResNo) {
2608- Results.push_back(Call);
2609- continue;
2610- }
2611- MachinePointerInfo PtrInfo;
2612- SDValue LoadResult =
2613- getLoad(Node->getValueType(ResNo), DL, CallChain, ResultPtr, PtrInfo);
2614- SDValue OutChain = LoadResult.getValue(1);
2615-
2616- if (StoreSDNode *ST = ResultStores[ResNo]) {
2617- // Replace store with the library call.
2618- ReplaceAllUsesOfValueWith(SDValue(ST, 0), OutChain);
2619- PtrInfo = ST->getPointerInfo();
2620- } else {
2621- PtrInfo = MachinePointerInfo::getFixedStack(
2622- getMachineFunction(), cast<FrameIndexSDNode>(ResultPtr)->getIndex());
2623- }
2624-
2625- Results.push_back(LoadResult);
2626- }
2627-
2628- return true;
2629- }
2630-
26312470SDValue SelectionDAG::expandVAArg(SDNode *Node) {
26322471 SDLoc dl(Node);
26332472 const TargetLowering &TLI = getTargetLoweringInfo();
0 commit comments