xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/ABI.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- ABI.h - Coroutine lowering class definitions (ABIs) ----*- C++ -*---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // This file defines coroutine lowering classes. The interface for coroutine
9 // lowering is defined by BaseABI. Each lowering method (ABI) implements the
10 // interface. Note that the enum class ABI, such as ABI::Switch, determines
11 // which ABI class, such as SwitchABI, is used to lower the coroutine. Both the
12 // ABI enum and ABI class are used by the Coroutine passes when lowering.
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_TRANSFORMS_COROUTINES_ABI_H
16 #define LLVM_TRANSFORMS_COROUTINES_ABI_H
17 
18 #include "llvm/Analysis/TargetTransformInfo.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Transforms/Coroutines/CoroShape.h"
21 #include "llvm/Transforms/Coroutines/MaterializationUtils.h"
22 #include "llvm/Transforms/Coroutines/SuspendCrossingInfo.h"
23 
24 namespace llvm {
25 
26 class Function;
27 
28 namespace coro {
29 
30 // This interface/API is to provide an object oriented way to implement ABI
31 // functionality. This is intended to replace use of the ABI enum to perform
32 // ABI operations. The ABIs (e.g. Switch, Async, Retcon{Once}) are the common
33 // ABIs. However, specific users may need to modify the behavior of these. This
34 // can be accomplished by inheriting one of the common ABIs and overriding one
35 // or more of the methods to create a custom ABI. To use a custom ABI for a
36 // given coroutine the coro.begin.custom.abi intrinsic is used in place of the
37 // coro.begin intrinsic. This takes an additional i32 arg that specifies the
38 // index of an ABI generator for the custom ABI object in a SmallVector passed
39 // to CoroSplitPass ctor.
40 
41 class LLVM_ABI BaseABI {
42 public:
BaseABI(Function & F,coro::Shape & S,std::function<bool (Instruction &)> IsMaterializable)43   BaseABI(Function &F, coro::Shape &S,
44           std::function<bool(Instruction &)> IsMaterializable)
45       : F(F), Shape(S), IsMaterializable(std::move(IsMaterializable)) {}
46   virtual ~BaseABI() = default;
47 
48   // Initialize the coroutine ABI
49   virtual void init() = 0;
50 
51   // Allocate the coroutine frame and do spill/reload as needed.
52   virtual void buildCoroutineFrame(bool OptimizeFrame);
53 
54   // Perform the function splitting according to the ABI.
55   virtual void splitCoroutine(Function &F, coro::Shape &Shape,
56                               SmallVectorImpl<Function *> &Clones,
57                               TargetTransformInfo &TTI) = 0;
58 
59   Function &F;
60   coro::Shape &Shape;
61 
62   // Callback used by coro::BaseABI::buildCoroutineFrame for rematerialization.
63   // It is provided to coro::doMaterializations(..).
64   std::function<bool(Instruction &I)> IsMaterializable;
65 };
66 
67 class LLVM_ABI SwitchABI : public BaseABI {
68 public:
SwitchABI(Function & F,coro::Shape & S,std::function<bool (Instruction &)> IsMaterializable)69   SwitchABI(Function &F, coro::Shape &S,
70             std::function<bool(Instruction &)> IsMaterializable)
71       : BaseABI(F, S, std::move(IsMaterializable)) {}
72 
73   void init() override;
74 
75   void splitCoroutine(Function &F, coro::Shape &Shape,
76                       SmallVectorImpl<Function *> &Clones,
77                       TargetTransformInfo &TTI) override;
78 };
79 
80 class LLVM_ABI AsyncABI : public BaseABI {
81 public:
AsyncABI(Function & F,coro::Shape & S,std::function<bool (Instruction &)> IsMaterializable)82   AsyncABI(Function &F, coro::Shape &S,
83            std::function<bool(Instruction &)> IsMaterializable)
84       : BaseABI(F, S, std::move(IsMaterializable)) {}
85 
86   void init() override;
87 
88   void splitCoroutine(Function &F, coro::Shape &Shape,
89                       SmallVectorImpl<Function *> &Clones,
90                       TargetTransformInfo &TTI) override;
91 };
92 
93 class LLVM_ABI AnyRetconABI : public BaseABI {
94 public:
AnyRetconABI(Function & F,coro::Shape & S,std::function<bool (Instruction &)> IsMaterializable)95   AnyRetconABI(Function &F, coro::Shape &S,
96                std::function<bool(Instruction &)> IsMaterializable)
97       : BaseABI(F, S, std::move(IsMaterializable)) {}
98 
99   void init() override;
100 
101   void splitCoroutine(Function &F, coro::Shape &Shape,
102                       SmallVectorImpl<Function *> &Clones,
103                       TargetTransformInfo &TTI) override;
104 };
105 
106 } // end namespace coro
107 
108 } // end namespace llvm
109 
110 #endif // LLVM_TRANSFORMS_COROUTINES_ABI_H
111