LLVM: lib/Transforms/Coroutines/CoroCleanup.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

17

18using namespace llvm;

19

20#define DEBUG_TYPE "coro-cleanup"

21

22namespace {

23

26 Lowerer(Module &M) : LowererBase(M), Builder(Context) {}

28};

29}

30

34 int Index = SubFn->getIndex();

35

37 {Builder.getPtrTy(), Builder.getPtrTy()});

38

41 auto *Load = Builder.CreateLoad(FrameTy->getElementType(Index), Gep);

42

44}

45

47 bool IsPrivateAndUnprocessed = F.isPresplitCoroutine() && F.hasLocalLinkage();

48 bool Changed = false;

49

51 if (auto *II = dyn_cast(&I)) {

52 switch (II->getIntrinsicID()) {

53 default:

54 continue;

55 case Intrinsic::coro_begin:

56 case Intrinsic::coro_begin_custom_abi:

57 II->replaceAllUsesWith(II->getArgOperand(1));

58 break;

59 case Intrinsic::coro_free:

60 II->replaceAllUsesWith(II->getArgOperand(1));

61 break;

62 case Intrinsic::coro_alloc:

64 break;

65 case Intrinsic::coro_async_resume:

66 II->replaceAllUsesWith(

68 break;

69 case Intrinsic::coro_id:

70 case Intrinsic::coro_id_retcon:

71 case Intrinsic::coro_id_retcon_once:

72 case Intrinsic::coro_id_async:

74 break;

75 case Intrinsic::coro_subfn_addr:

77 break;

78 case Intrinsic::coro_end:

79 case Intrinsic::coro_suspend_retcon:

80 if (IsPrivateAndUnprocessed) {

82 } else

83 continue;

84 break;

85 case Intrinsic::coro_async_size_replace:

86 auto *Target = cast(

87 cast(II->getArgOperand(0)->stripPointerCasts())

88 ->getInitializer());

89 auto *Source = cast(

90 cast(II->getArgOperand(1)->stripPointerCasts())

91 ->getInitializer());

92 auto *TargetSize = Target->getOperand(1);

93 auto *SourceSize = Source->getOperand(1);

94 if (TargetSize->isElementWiseEqual(SourceSize)) {

95 break;

96 }

97 auto *TargetRelativeFunOffset = Target->getOperand(0);

99 Target->getType(), TargetRelativeFunOffset, SourceSize);

100 Target->replaceAllUsesWith(NewFuncPtrStruct);

101 break;

102 }

103 II->eraseFromParent();

104 Changed = true;

105 }

106 }

107

108 return Changed;

109}

110

113 M, {"llvm.coro.alloc", "llvm.coro.begin", "llvm.coro.subfn.addr",

114 "llvm.coro.free", "llvm.coro.id", "llvm.coro.id.retcon",

115 "llvm.coro.id.async", "llvm.coro.id.retcon.once",

116 "llvm.coro.async.size.replace", "llvm.coro.async.resume",

117 "llvm.coro.begin.custom.abi"});

118}

119

124

127

130

133

134 Lowerer L(M);

135 for (auto &F : M) {

136 if (L.lower(F)) {

139 }

140 }

141

143}

Expand Atomic instructions

static bool declaresCoroCleanupIntrinsics(const Module &M)

static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn)

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

ModuleAnalysisManager MAM

This file provides the interface for the pass responsible for both simplifying and canonicalizing the...

static const unsigned FramePtr

A container for analyses that lazily runs them and caches their results.

void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)

Invalidate cached analyses for an IR unit.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represents analyses that only rely on functions' control flow.

static ConstantInt * getTrue(LLVMContext &Context)

static ConstantPointerNull * get(PointerType *T)

Static factory methods - Return objects of the specified value.

static Constant * get(StructType *T, ArrayRef< Constant * > V)

static ConstantTokenNone * get(LLVMContext &Context)

Return the ConstantTokenNone.

This class represents the llvm.coro.subfn.addr instruction.

ResumeKind getIndex() const

LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)

Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...

Value * CreateConstInBoundsGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name="")

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...

A Module instance is used to store all the information related to an LLVM module.

LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)

PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)

Run all of the passes in this manager over the given unit of IR.

static PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

void preserveSet()

Mark an analysis set as preserved.

A pass to simplify and canonicalize the CFG of a function.

static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)

This static method is the primary way to create a literal StructType.

Target - Wrapper for Target specific information.

LLVM Value Representation.

void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

LLVMContext & getContext() const

All values hold a context through their type.

bool declaresIntrinsics(const Module &M, const std::initializer_list< StringRef >)

This is an optimization pass for GlobalISel generic memory operations.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)