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