]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Transforms/Coroutines/CoroInternal.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304460, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Transforms / Coroutines / CoroInternal.h
1 //===- CoroInternal.h - Internal Coroutine interfaces ---------*- C++ -*---===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Common definitions/declarations used internally by coroutine lowering passes.
10 //===----------------------------------------------------------------------===//
11
12 #ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H
13 #define LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H
14
15 #include "CoroInstr.h"
16 #include "llvm/Transforms/Coroutines.h"
17
18 namespace llvm {
19
20 class CallGraph;
21 class CallGraphSCC;
22 class PassRegistry;
23
24 void initializeCoroEarlyPass(PassRegistry &);
25 void initializeCoroSplitPass(PassRegistry &);
26 void initializeCoroElidePass(PassRegistry &);
27 void initializeCoroCleanupPass(PassRegistry &);
28
29 // CoroEarly pass marks every function that has coro.begin with a string
30 // attribute "coroutine.presplit"="0". CoroSplit pass processes the coroutine
31 // twice. First, it lets it go through complete IPO optimization pipeline as a
32 // single function. It forces restart of the pipeline by inserting an indirect
33 // call to an empty function "coro.devirt.trigger" which is devirtualized by
34 // CoroElide pass that triggers a restart of the pipeline by CGPassManager.
35 // When CoroSplit pass sees the same coroutine the second time, it splits it up,
36 // adds coroutine subfunctions to the SCC to be processed by IPO pipeline.
37
38 #define CORO_PRESPLIT_ATTR "coroutine.presplit"
39 #define UNPREPARED_FOR_SPLIT "0"
40 #define PREPARED_FOR_SPLIT "1"
41
42 #define CORO_DEVIRT_TRIGGER_FN "coro.devirt.trigger"
43
44 namespace coro {
45
46 bool declaresIntrinsics(Module &M, std::initializer_list<StringRef>);
47 void replaceAllCoroAllocs(CoroBeginInst *CB, bool Replacement);
48 void replaceAllCoroFrees(CoroBeginInst *CB, Value *Replacement);
49 void replaceCoroFree(CoroIdInst *CoroId, bool Elide);
50 void updateCallGraph(Function &Caller, ArrayRef<Function *> Funcs,
51                      CallGraph &CG, CallGraphSCC &SCC);
52
53 // Keeps data and helper functions for lowering coroutine intrinsics.
54 struct LowererBase {
55   Module &TheModule;
56   LLVMContext &Context;
57   PointerType *const Int8Ptr;
58   FunctionType *const ResumeFnType;
59   ConstantPointerNull *const NullPtr;
60
61   LowererBase(Module &M);
62   Value *makeSubFnCall(Value *Arg, int Index, Instruction *InsertPt);
63 };
64
65 // Holds structural Coroutine Intrinsics for a particular function and other
66 // values used during CoroSplit pass.
67 struct LLVM_LIBRARY_VISIBILITY Shape {
68   CoroBeginInst *CoroBegin;
69   SmallVector<CoroEndInst *, 4> CoroEnds;
70   SmallVector<CoroSizeInst *, 2> CoroSizes;
71   SmallVector<CoroSuspendInst *, 4> CoroSuspends;
72
73   // Field Indexes for known coroutine frame fields.
74   enum {
75     ResumeField,
76     DestroyField,
77     PromiseField,
78     IndexField,
79     LastKnownField = IndexField
80   };
81
82   StructType *FrameTy;
83   Instruction *FramePtr;
84   BasicBlock *AllocaSpillBlock;
85   SwitchInst *ResumeSwitch;
86   AllocaInst *PromiseAlloca;
87   bool HasFinalSuspend;
88
89   IntegerType *getIndexType() const {
90     assert(FrameTy && "frame type not assigned");
91     return cast<IntegerType>(FrameTy->getElementType(IndexField));
92   }
93   ConstantInt *getIndex(uint64_t Value) const {
94     return ConstantInt::get(getIndexType(), Value);
95   }
96
97   Shape() = default;
98   explicit Shape(Function &F) { buildFrom(F); }
99   void buildFrom(Function &F);
100 };
101
102 void buildCoroutineFrame(Function &F, Shape &Shape);
103
104 } // End namespace coro.
105 } // End namespace llvm
106
107 #endif