Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ class TargetTransformInfoImplBase {
case Intrinsic::experimental_gc_relocate:
case Intrinsic::coro_alloc:
case Intrinsic::coro_begin:
case Intrinsic::coro_begin_custom_abi:
case Intrinsic::coro_free:
case Intrinsic::coro_end:
case Intrinsic::coro_frame:
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -1709,7 +1709,8 @@ def int_coro_prepare_async : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
[IntrNoMem]>;
def int_coro_begin : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
[WriteOnly<ArgIndex<1>>]>;

def int_coro_begin_custom_abi : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty, llvm_i32_ty],
[WriteOnly<ArgIndex<1>>]>;
def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly,
ReadOnly<ArgIndex<1>>,
Expand Down
115 changes: 115 additions & 0 deletions llvm/include/llvm/Transforms/Coroutines/ABI.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//===- ABI.h - Coroutine ABI Transformers ---------------------*- C++ -*---===//
//
// 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 declares the pass that analyzes a function for coroutine intrs and
// a transformer class that contains methods for handling different steps of
// coroutine lowering.
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_COROUTINES_ABI_H
#define LLVM_TRANSFORMS_COROUTINES_ABI_H

#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Transforms/Coroutines/CoroShape.h"
#include "llvm/Transforms/Coroutines/MaterializationUtils.h"
#include "llvm/Transforms/Coroutines/SuspendCrossingInfo.h"

namespace llvm {

class Function;

namespace coro {

// This interface/API is to provide an object oriented way to implement ABI
// functionality. This is intended to replace use of the ABI enum to perform
// ABI operations. The ABIs (e.g. Switch, Async, Retcon{Once}) are the common
// ABIs. However, specific users often need to modify the behavior of these,
// such as for C++20 or Swift. This can be accomplished by inheriting one of
// the common ABIs and overriding one or more of the methods to create a custom
// ABI. The custom ABI is specified with the coro.begin.custom.abi intrinsic
// instead of the coro.begin intrinsic by providing an i32 in the last arg.
// This is used to lookup a generator for the custom ABI from a set of
// generators provided to the CoroSplitPass constructor.

class BaseABI {
public:
BaseABI(Function &F, Shape &S)
: F(F), Shape(S), IsMaterializable(coro::isTriviallyMaterializable) {}

BaseABI(Function &F, coro::Shape &S,
std::function<bool(Instruction &)> IsMaterializable)
: F(F), Shape(S), IsMaterializable(IsMaterializable) {}

// Initialize the coroutine ABI
virtual void init() = 0;

// Allocate the coroutine frame and do spill/reload as needed.
virtual void buildCoroutineFrame(bool OptimizeFrame);

// Perform the function splitting according to the ABI.
virtual void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) = 0;

Function &F;
coro::Shape &Shape;

// Callback used by coro::BaseABI::buildCoroutineFrame for rematerialization.
// It is provided to coro::doMaterializations(..).
std::function<bool(Instruction &I)> IsMaterializable;
};

class SwitchABI : public BaseABI {
public:
SwitchABI(Function &F, coro::Shape &S) : BaseABI(F, S) {}

SwitchABI(Function &F, coro::Shape &S,
std::function<bool(Instruction &)> IsMaterializable)
: BaseABI(F, S, IsMaterializable) {}

void init() override;

void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) override;
};

class AsyncABI : public BaseABI {
public:
AsyncABI(Function &F, coro::Shape &S) : BaseABI(F, S) {}

AsyncABI(Function &F, coro::Shape &S,
std::function<bool(Instruction &)> IsMaterializable)
: BaseABI(F, S, IsMaterializable) {}

void init() override;

void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) override;
};

class AnyRetconABI : public BaseABI {
public:
AnyRetconABI(Function &F, coro::Shape &S) : BaseABI(F, S) {}

AnyRetconABI(Function &F, coro::Shape &S,
std::function<bool(Instruction &)> IsMaterializable)
: BaseABI(F, S, IsMaterializable) {}

void init() override;

void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) override;
};

} // end namespace coro

} // end namespace llvm

#endif // LLVM_TRANSFORMS_COROUTINES_ABI_H
Loading