[ARM] Rejig MVE load store tests. NFC
[llvm-core.git] / lib / Transforms / Coroutines / CoroInternal.h
blob441c8a20f1f3a5c60141307d80d517780164c1ef
1 //===- CoroInternal.h - Internal Coroutine interfaces ---------*- 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 // Common definitions/declarations used internally by coroutine lowering passes.
9 //===----------------------------------------------------------------------===//
11 #ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H
12 #define LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H
14 #include "CoroInstr.h"
15 #include "llvm/Transforms/Coroutines.h"
17 namespace llvm {
19 class CallGraph;
20 class CallGraphSCC;
21 class PassRegistry;
23 void initializeCoroEarlyPass(PassRegistry &);
24 void initializeCoroSplitPass(PassRegistry &);
25 void initializeCoroElidePass(PassRegistry &);
26 void initializeCoroCleanupPass(PassRegistry &);
28 // CoroEarly pass marks every function that has coro.begin with a string
29 // attribute "coroutine.presplit"="0". CoroSplit pass processes the coroutine
30 // twice. First, it lets it go through complete IPO optimization pipeline as a
31 // single function. It forces restart of the pipeline by inserting an indirect
32 // call to an empty function "coro.devirt.trigger" which is devirtualized by
33 // CoroElide pass that triggers a restart of the pipeline by CGPassManager.
34 // When CoroSplit pass sees the same coroutine the second time, it splits it up,
35 // adds coroutine subfunctions to the SCC to be processed by IPO pipeline.
37 #define CORO_PRESPLIT_ATTR "coroutine.presplit"
38 #define UNPREPARED_FOR_SPLIT "0"
39 #define PREPARED_FOR_SPLIT "1"
41 #define CORO_DEVIRT_TRIGGER_FN "coro.devirt.trigger"
43 namespace coro {
45 bool declaresIntrinsics(Module &M, std::initializer_list<StringRef>);
46 void replaceAllCoroAllocs(CoroBeginInst *CB, bool Replacement);
47 void replaceAllCoroFrees(CoroBeginInst *CB, Value *Replacement);
48 void replaceCoroFree(CoroIdInst *CoroId, bool Elide);
49 void updateCallGraph(Function &Caller, ArrayRef<Function *> Funcs,
50 CallGraph &CG, CallGraphSCC &SCC);
52 // Keeps data and helper functions for lowering coroutine intrinsics.
53 struct LowererBase {
54 Module &TheModule;
55 LLVMContext &Context;
56 PointerType *const Int8Ptr;
57 FunctionType *const ResumeFnType;
58 ConstantPointerNull *const NullPtr;
60 LowererBase(Module &M);
61 Value *makeSubFnCall(Value *Arg, int Index, Instruction *InsertPt);
64 // Holds structural Coroutine Intrinsics for a particular function and other
65 // values used during CoroSplit pass.
66 struct LLVM_LIBRARY_VISIBILITY Shape {
67 CoroBeginInst *CoroBegin;
68 SmallVector<CoroEndInst *, 4> CoroEnds;
69 SmallVector<CoroSizeInst *, 2> CoroSizes;
70 SmallVector<CoroSuspendInst *, 4> CoroSuspends;
72 // Field Indexes for known coroutine frame fields.
73 enum {
74 ResumeField,
75 DestroyField,
76 PromiseField,
77 IndexField,
80 StructType *FrameTy;
81 Instruction *FramePtr;
82 BasicBlock *AllocaSpillBlock;
83 SwitchInst *ResumeSwitch;
84 AllocaInst *PromiseAlloca;
85 bool HasFinalSuspend;
87 IntegerType *getIndexType() const {
88 assert(FrameTy && "frame type not assigned");
89 return cast<IntegerType>(FrameTy->getElementType(IndexField));
91 ConstantInt *getIndex(uint64_t Value) const {
92 return ConstantInt::get(getIndexType(), Value);
95 Shape() = default;
96 explicit Shape(Function &F) { buildFrom(F); }
97 void buildFrom(Function &F);
100 void buildCoroutineFrame(Function &F, Shape &Shape);
102 } // End namespace coro.
103 } // End namespace llvm
105 #endif