Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:38

0001 //===- ABI.h - Coroutine lowering class definitions (ABIs) ----*- C++ -*---===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 // This file defines coroutine lowering classes. The interface for coroutine
0009 // lowering is defined by BaseABI. Each lowering method (ABI) implements the
0010 // interface. Note that the enum class ABI, such as ABI::Switch, determines
0011 // which ABI class, such as SwitchABI, is used to lower the coroutine. Both the
0012 // ABI enum and ABI class are used by the Coroutine passes when lowering.
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_TRANSFORMS_COROUTINES_ABI_H
0016 #define LLVM_TRANSFORMS_COROUTINES_ABI_H
0017 
0018 #include "llvm/Analysis/TargetTransformInfo.h"
0019 #include "llvm/Transforms/Coroutines/CoroShape.h"
0020 #include "llvm/Transforms/Coroutines/MaterializationUtils.h"
0021 #include "llvm/Transforms/Coroutines/SuspendCrossingInfo.h"
0022 
0023 namespace llvm {
0024 
0025 class Function;
0026 
0027 namespace coro {
0028 
0029 // This interface/API is to provide an object oriented way to implement ABI
0030 // functionality. This is intended to replace use of the ABI enum to perform
0031 // ABI operations. The ABIs (e.g. Switch, Async, Retcon{Once}) are the common
0032 // ABIs. However, specific users may need to modify the behavior of these. This
0033 // can be accomplished by inheriting one of the common ABIs and overriding one
0034 // or more of the methods to create a custom ABI. To use a custom ABI for a
0035 // given coroutine the coro.begin.custom.abi intrinsic is used in place of the
0036 // coro.begin intrinsic. This takes an additional i32 arg that specifies the
0037 // index of an ABI generator for the custom ABI object in a SmallVector passed
0038 // to CoroSplitPass ctor.
0039 
0040 class BaseABI {
0041 public:
0042   BaseABI(Function &F, coro::Shape &S,
0043           std::function<bool(Instruction &)> IsMaterializable)
0044       : F(F), Shape(S), IsMaterializable(std::move(IsMaterializable)) {}
0045   virtual ~BaseABI() = default;
0046 
0047   // Initialize the coroutine ABI
0048   virtual void init() = 0;
0049 
0050   // Allocate the coroutine frame and do spill/reload as needed.
0051   virtual void buildCoroutineFrame(bool OptimizeFrame);
0052 
0053   // Perform the function splitting according to the ABI.
0054   virtual void splitCoroutine(Function &F, coro::Shape &Shape,
0055                               SmallVectorImpl<Function *> &Clones,
0056                               TargetTransformInfo &TTI) = 0;
0057 
0058   Function &F;
0059   coro::Shape &Shape;
0060 
0061   // Callback used by coro::BaseABI::buildCoroutineFrame for rematerialization.
0062   // It is provided to coro::doMaterializations(..).
0063   std::function<bool(Instruction &I)> IsMaterializable;
0064 };
0065 
0066 class SwitchABI : public BaseABI {
0067 public:
0068   SwitchABI(Function &F, coro::Shape &S,
0069             std::function<bool(Instruction &)> IsMaterializable)
0070       : BaseABI(F, S, std::move(IsMaterializable)) {}
0071 
0072   void init() override;
0073 
0074   void splitCoroutine(Function &F, coro::Shape &Shape,
0075                       SmallVectorImpl<Function *> &Clones,
0076                       TargetTransformInfo &TTI) override;
0077 };
0078 
0079 class AsyncABI : public BaseABI {
0080 public:
0081   AsyncABI(Function &F, coro::Shape &S,
0082            std::function<bool(Instruction &)> IsMaterializable)
0083       : BaseABI(F, S, std::move(IsMaterializable)) {}
0084 
0085   void init() override;
0086 
0087   void splitCoroutine(Function &F, coro::Shape &Shape,
0088                       SmallVectorImpl<Function *> &Clones,
0089                       TargetTransformInfo &TTI) override;
0090 };
0091 
0092 class AnyRetconABI : public BaseABI {
0093 public:
0094   AnyRetconABI(Function &F, coro::Shape &S,
0095                std::function<bool(Instruction &)> IsMaterializable)
0096       : BaseABI(F, S, std::move(IsMaterializable)) {}
0097 
0098   void init() override;
0099 
0100   void splitCoroutine(Function &F, coro::Shape &Shape,
0101                       SmallVectorImpl<Function *> &Clones,
0102                       TargetTransformInfo &TTI) override;
0103 };
0104 
0105 } // end namespace coro
0106 
0107 } // end namespace llvm
0108 
0109 #endif // LLVM_TRANSFORMS_COROUTINES_ABI_H