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