llvm/llvm/lib/Transforms/Coroutines/Coroutines.cpp

//===- Coroutines.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the common infrastructure for Coroutine Passes.
//
//===----------------------------------------------------------------------===//

#include "CoroInternal.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Transforms/Coroutines/ABI.h"
#include "llvm/Transforms/Coroutines/CoroInstr.h"
#include "llvm/Transforms/Coroutines/CoroShape.h"
#include "llvm/Transforms/Utils/Local.h"
#include <cassert>
#include <cstddef>
#include <utility>

usingnamespacellvm;

// Construct the lowerer base class and initialize its members.
coro::LowererBase::LowererBase(Module &M)
    :{}

// Creates a call to llvm.coro.subfn.addr to obtain a resume function address.
// It generates the following:
//
//    call ptr @llvm.coro.subfn.addr(ptr %Arg, i8 %index)

CallInst *coro::LowererBase::makeSubFnCall(Value *Arg, int Index,
                                           Instruction *InsertPt) {}

// NOTE: Must be sorted!
static const char *const CoroIntrinsics[] =;

#ifndef NDEBUG
static bool isCoroutineIntrinsicName(StringRef Name) {
  return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name, "coro") !=
         -1;
}
#endif

bool coro::isSuspendBlock(BasicBlock *BB) {}

bool coro::declaresAnyIntrinsic(const Module &M) {}

// Verifies if a module has named values listed. Also, in debug mode verifies
// that names are intrinsic names.
bool coro::declaresIntrinsics(const Module &M,
                              const std::initializer_list<StringRef> List) {}

// Replace all coro.frees associated with the provided CoroId either with 'null'
// if Elide is true and with its frame parameter otherwise.
void coro::replaceCoroFree(CoroIdInst *CoroId, bool Elide) {}

void coro::suppressCoroAllocs(CoroIdInst *CoroId) {}

// Replacing llvm.coro.alloc with false will suppress dynamic
// allocation as it is expected for the frontend to generate the code that
// looks like:
//   id = coro.id(...)
//   mem = coro.alloc(id) ? malloc(coro.size()) : 0;
//   coro.begin(id, mem)
void coro::suppressCoroAllocs(LLVMContext &Context,
                              ArrayRef<CoroAllocInst *> CoroAllocs) {}

static CoroSaveInst *createCoroSave(CoroBeginInst *CoroBegin,
                                    CoroSuspendInst *SuspendInst) {}

// Collect "interesting" coroutine intrinsics.
void coro::Shape::analyze(Function &F,
                          SmallVectorImpl<CoroFrameInst *> &CoroFrames,
                          SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves) {}

// If for some reason, we were not able to find coro.begin, bailout.
void coro::Shape::invalidateCoroutine(
    Function &F, SmallVectorImpl<CoroFrameInst *> &CoroFrames) {}

void coro::SwitchABI::init() {}

void coro::AsyncABI::init() {}

void coro::AnyRetconABI::init() {}

void coro::Shape::cleanCoroutine(
    SmallVectorImpl<CoroFrameInst *> &CoroFrames,
    SmallVectorImpl<CoroSaveInst *> &UnusedCoroSaves) {}

static void propagateCallAttrsFromCallee(CallInst *Call, Function *Callee) {}

static void addCallToCallGraph(CallGraph *CG, CallInst *Call, Function *Callee){}

Value *coro::Shape::emitAlloc(IRBuilder<> &Builder, Value *Size,
                              CallGraph *CG) const {}

void coro::Shape::emitDealloc(IRBuilder<> &Builder, Value *Ptr,
                              CallGraph *CG) const {}

[[noreturn]] static void fail(const Instruction *I, const char *Reason,
                              Value *V) {}

/// Check that the given value is a well-formed prototype for the
/// llvm.coro.id.retcon.* intrinsics.
static void checkWFRetconPrototype(const AnyCoroIdRetconInst *I, Value *V) {}

/// Check that the given value is a well-formed allocator.
static void checkWFAlloc(const Instruction *I, Value *V) {}

/// Check that the given value is a well-formed deallocator.
static void checkWFDealloc(const Instruction *I, Value *V) {}

static void checkConstantInt(const Instruction *I, Value *V,
                             const char *Reason) {}

void AnyCoroIdRetconInst::checkWellFormed() const {}

static void checkAsyncFuncPointer(const Instruction *I, Value *V) {}

void CoroIdAsyncInst::checkWellFormed() const {}

static void checkAsyncContextProjectFunction(const Instruction *I,
                                             Function *F) {}

void CoroSuspendAsyncInst::checkWellFormed() const {}

void CoroAsyncEndInst::checkWellFormed() const {}