|
LLVM 24.0.0git
|
#include "llvm/Transforms/Coroutines/CoroSplit.h"#include "CoroCloner.h"#include "CoroInternal.h"#include "llvm/ADT/DenseMap.h"#include "llvm/ADT/PriorityWorklist.h"#include "llvm/ADT/STLExtras.h"#include "llvm/ADT/SmallPtrSet.h"#include "llvm/ADT/SmallVector.h"#include "llvm/ADT/StringExtras.h"#include "llvm/ADT/StringRef.h"#include "llvm/ADT/Twine.h"#include "llvm/Analysis/BlockFrequencyInfo.h"#include "llvm/Analysis/CFG.h"#include "llvm/Analysis/CallGraph.h"#include "llvm/Analysis/ConstantFolding.h"#include "llvm/Analysis/LazyCallGraph.h"#include "llvm/Analysis/OptimizationRemarkEmitter.h"#include "llvm/Analysis/TargetTransformInfo.h"#include "llvm/BinaryFormat/Dwarf.h"#include "llvm/IR/Argument.h"#include "llvm/IR/Attributes.h"#include "llvm/IR/BasicBlock.h"#include "llvm/IR/CFG.h"#include "llvm/IR/Constants.h"#include "llvm/IR/DIBuilder.h"#include "llvm/IR/DataLayout.h"#include "llvm/IR/DebugInfo.h"#include "llvm/IR/DerivedTypes.h"#include "llvm/IR/Dominators.h"#include "llvm/IR/GlobalValue.h"#include "llvm/IR/GlobalVariable.h"#include "llvm/IR/InstIterator.h"#include "llvm/IR/InstrTypes.h"#include "llvm/IR/Instruction.h"#include "llvm/IR/Instructions.h"#include "llvm/IR/IntrinsicInst.h"#include "llvm/IR/LLVMContext.h"#include "llvm/IR/MDBuilder.h"#include "llvm/IR/Module.h"#include "llvm/IR/ProfDataUtils.h"#include "llvm/IR/Type.h"#include "llvm/IR/Value.h"#include "llvm/IR/Verifier.h"#include "llvm/Support/Casting.h"#include "llvm/Support/Debug.h"#include "llvm/Support/PrettyStackTrace.h"#include "llvm/Support/raw_ostream.h"#include "llvm/Transforms/Coroutines/MaterializationUtils.h"#include "llvm/Transforms/Scalar.h"#include "llvm/Transforms/Utils/BasicBlockUtils.h"#include "llvm/Transforms/Utils/CallGraphUpdater.h"#include "llvm/Transforms/Utils/Cloning.h"#include "llvm/Transforms/Utils/Local.h"#include <cassert>#include <cstddef>#include <cstdint>#include <initializer_list>#include <iterator>Go to the source code of this file.
Macros | |
| #define | DEBUG_TYPE "coro-split" |
| #define DEBUG_TYPE "coro-split" |
Definition at line 82 of file CoroSplit.cpp.
|
static |
Definition at line 921 of file CoroSplit.cpp.
Referenced by llvm::coro::BaseCloner::create().
|
static |
Definition at line 906 of file CoroSplit.cpp.
References Size, and uint64_t.
Referenced by llvm::coro::BaseCloner::create().
|
static |
Definition at line 2238 of file CoroSplit.cpp.
References llvm::SmallVectorTemplateBase< T, bool >::push_back().
Referenced by llvm::CoroSplitPass::run().
|
static |
Definition at line 928 of file CoroSplit.cpp.
Referenced by llvm::coro::BaseCloner::create().
|
static |
Coerce the arguments in FnArgs according to FnTy in CallArgs.
Definition at line 1770 of file CoroSplit.cpp.
References assert(), getType(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), and llvm::ArrayRef< T >::size().
Referenced by llvm::coro::createMustTailCall().
|
static |
Returns all debug records in F.
Definition at line 686 of file CoroSplit.cpp.
References F, llvm::filterDbgVars(), I, instructions, and llvm::SmallVectorTemplateBase< T, bool >::push_back().
Referenced by doSplitCoroutine(), and llvm::coro::BaseCloner::salvageDebugInfo().
|
static |
Definition at line 504 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Async, llvm::Function::Create(), llvm::GlobalValue::getAddressSpace(), getFunctionTypeFromAsyncSuspend(), llvm::Value::getName(), llvm::GlobalValue::getParent(), llvm::coro::Shape::getResumeFunctionType(), and llvm::GlobalValue::InternalLinkage.
Referenced by llvm::coro::SwitchCloner::create(), llvm::coro::AnyRetconABI::splitCoroutine(), and llvm::coro::AsyncABI::splitCoroutine().
|
static |
Definition at line 2247 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Async, llvm::coro::Shape::CoroBegin, F, llvm::CoroBeginInst::getCustomABI(), llvm::CoroBeginInst::hasCustomABI(), llvm_unreachable, llvm::coro::Retcon, llvm::coro::RetconOnce, llvm::SmallVectorTemplateCommon< T, typename >::size(), and llvm::coro::Switch.
Referenced by llvm::CoroSplitPass::CoroSplitPass(), llvm::CoroSplitPass::CoroSplitPass(), llvm::CoroSplitPass::CoroSplitPass(), and llvm::CoroSplitPass::CoroSplitPass().
|
static |
Create a pointer to the switch destroy function field in the coroutine frame.
Definition at line 171 of file CoroSplit.cpp.
References llvm::coro::Shape::SwitchLoweringStorage::DestroyOffset, FramePtr, llvm::Type::getInt64Ty(), llvm::Offset, and llvm::coro::Shape::SwitchLowering.
Referenced by replaceSwitchResumeCoroFree().
|
static |
Create a pointer to the switch index field in the coroutine frame.
Definition at line 357 of file CoroSplit.cpp.
References FramePtr, llvm::Type::getInt64Ty(), llvm::coro::Shape::SwitchLoweringStorage::IndexOffset, llvm::Offset, and llvm::coro::Shape::SwitchLowering.
Referenced by markCoroutineAsDone().
|
static |
Definition at line 2086 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), collectDbgVariableRecords(), llvm::coro::Shape::CoroBegin, llvm::coro::Shape::CoroSuspends, F, handleNoSuspendCoroutine(), llvm::coro::Shape::SwitchLoweringStorage::HasCoroElideNoAllocVariant, hasSafeElideCaller(), lowerAwaitSuspends(), llvm::coro::normalizeCoroutine(), removeCoroEndsFromRampFunction(), removeCoroIsInRampFromRampFunction(), replaceFrameSizeAndAlignment(), replaceSwiftErrorOps(), llvm::coro::salvageDebugInfo(), llvm::coro::Shape::Shape(), simplifySuspendPoints(), llvm::coro::Switch, and llvm::coro::Shape::SwitchLowering.
Referenced by llvm::CoroSplitPass::run().
|
static |
Returns the location of the first instruction after ActiveSuspend with a non-zero line, or an empty location if there is none.
Definition at line 800 of file CoroSplit.cpp.
References DL, llvm::dyn_cast_or_null(), llvm::BasicBlock::end(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::ilist_node_with_parent< NodeTy, ParentTy, Options >::getNextNode(), llvm::skipDebugIntrinsics(), and llvm::Successor.
Referenced by llvm::coro::BaseCloner::deriveNewFramePointer(), and updateScopeLine().
|
static |
Definition at line 496 of file CoroSplit.cpp.
References llvm::cast(), llvm::FunctionType::get(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), and llvm::Type::getVoidTy().
Referenced by createCloneDeclaration().
|
static |
Definition at line 1224 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Async, llvm::coro::Shape::CoroBegin, llvm::coro::elideCoroFree(), llvm::Instruction::eraseFromParent(), llvm::coro::Shape::FrameAlign, llvm::coro::Shape::FrameSize, llvm::ArrayType::get(), llvm::PoisonValue::get(), llvm::AnyCoroIdInst::getCoroAlloc(), llvm::Type::getInt8Ty(), llvm::coro::Shape::getSwitchCoroId(), llvm::coro::Retcon, llvm::coro::RetconOnce, and llvm::coro::Switch.
Referenced by doSplitCoroutine().
|
static |
Definition at line 1302 of file CoroSplit.cpp.
References llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), hasCallsInBlockBetween(), and hasCallsInBlocksBetween().
Referenced by simplifySuspendPoint().
|
static |
Definition at line 1261 of file CoroSplit.cpp.
References I, and llvm::isa().
Referenced by hasCallsBetween(), and hasCallsInBlocksBetween().
|
static |
Definition at line 1273 of file CoroSplit.cpp.
References llvm::SmallVectorTemplateCommon< T, typename >::empty(), hasCallsInBlockBetween(), llvm::SmallVectorImpl< T >::pop_back_val(), llvm::predecessors(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().
Referenced by hasCallsBetween().
Definition at line 2068 of file CoroSplit.cpp.
References llvm::dyn_cast(), and F.
Referenced by doSplitCoroutine().
|
static |
Definition at line 88 of file CoroSplit.cpp.
References Call, llvm::dyn_cast(), llvm::Instruction::eraseFromParent(), FramePtr, llvm::FunctionType::get(), llvm::CallBase::getAttributes(), llvm::CoroAwaitSuspendInst::getAwaiter(), llvm::CallBase::getCalledFunction(), llvm::Value::getContext(), llvm::CoroAwaitSuspendInst::getFrame(), llvm::Function::getIntrinsicID(), llvm::PointerType::getUnqual(), llvm::Type::getVoidTy(), llvm::CoroAwaitSuspendInst::getWrapperFunction(), llvm_unreachable, llvm::coro::LowererBase::makeSubFnCall(), llvm::Value::replaceAllUsesWith(), llvm::CoroSubFnInst::ResumeIndex, llvm::coro::Shape::SymmetricTransfers, and Wrapper.
Referenced by lowerAwaitSuspends().
|
static |
Definition at line 153 of file CoroSplit.cpp.
References llvm::coro::Shape::CoroAwaitSuspends, F, and lowerAwaitSuspend().
Referenced by doSplitCoroutine().
|
static |
Definition at line 372 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), llvm::cast(), llvm::coro::Shape::CoroSuspends, createSwitchIndexPtr(), FramePtr, llvm::ConstantPointerNull::get(), llvm::coro::Shape::getIndex(), llvm::coro::Shape::getSwitchResumePointerType(), llvm::coro::Shape::SwitchLoweringStorage::HasFinalSuspend, llvm::coro::Shape::SwitchLoweringStorage::HasUnwindCoroEnd, llvm::coro::Switch, and llvm::coro::Shape::SwitchLowering.
Referenced by replaceUnwindCoroEnd().
|
static |
Definition at line 159 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), llvm::coro::Shape::emitDealloc(), FramePtr, llvm::coro::Shape::RetconLoweringStorage::IsFrameInlineInStorage, llvm::coro::Retcon, llvm::coro::Shape::RetconLowering, and llvm::coro::RetconOnce.
Referenced by replaceFallthroughCoroEnd(), and replaceUnwindCoroEnd().
|
static |
Definition at line 1210 of file CoroSplit.cpp.
References llvm::errs(), F, llvm::removeUnreachableBlocks(), llvm::report_fatal_error(), and llvm::verifyFunction().
Referenced by updateCallGraphAfterCoroutineSplit().
|
static |
Remove calls to llvm.coro.end in the original function.
Definition at line 2049 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Shape::CoroEnds, llvm::End, llvm::coro::Shape::FramePtr, replaceCoroEnd(), and llvm::coro::Switch.
Referenced by doSplitCoroutine().
|
static |
Definition at line 2060 of file CoroSplit.cpp.
References llvm::coro::Shape::CoroIsInRampInsts, llvm::ConstantInt::getTrue(), and II.
Referenced by doSplitCoroutine().
|
static |
Definition at line 2225 of file CoroSplit.cpp.
References C(), llvm::cast(), Changed, llvm::make_early_inc_range(), P, replacePrepare(), and llvm::Value::uses().
Referenced by llvm::CoroSplitPass::run().
|
static |
Definition at line 1755 of file CoroSplit.cpp.
References llvm::coro::Continuation, llvm::PoisonValue::get(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::CoroSuspendAsyncInst::getResumeFunction(), llvm::PointerType::getUnqual(), llvm::CoroSuspendAsyncInst::ResumeFunctionArg, and llvm::User::setOperand().
Referenced by llvm::coro::AsyncABI::splitCoroutine().
|
static |
Definition at line 438 of file CoroSplit.cpp.
References llvm::End, FramePtr, replaceFallthroughCoroEnd(), and replaceUnwindCoroEnd().
Referenced by removeCoroEndsFromRampFunction(), and llvm::coro::BaseCloner::replaceCoroEnds().
|
static |
Replace an llvm.coro.end.async.
Will inline the must tail call function call if there is one.
Definition at line 222 of file CoroSplit.cpp.
References assert(), llvm::cast(), llvm::dyn_cast(), llvm::End, and llvm::InlineFunction().
Referenced by replaceFallthroughCoroEnd().
|
static |
Replace a non-unwind call to llvm.coro.end.
Definition at line 265 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), llvm::coro::Async, llvm::cast(), llvm::dyn_cast(), llvm::End, FramePtr, llvm::ConstantPointerNull::get(), llvm::ConstantTokenNone::get(), llvm::PoisonValue::get(), llvm::coro::Shape::getResumeFunctionType(), llvm::FunctionType::getReturnType(), maybeFreeRetconStorage(), replaceCoroEndAsync(), llvm::coro::Retcon, llvm::coro::RetconOnce, and llvm::coro::Switch.
Referenced by replaceCoroEnd().
|
static |
Definition at line 1186 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Async, llvm::coro::Shape::CoroAligns, llvm::coro::Shape::CoroSizes, llvm::Instruction::eraseFromParent(), llvm::coro::Shape::FrameAlign, llvm::coro::Shape::FrameSize, llvm::TypeSize::getFixed(), llvm::Value::getType(), llvm::Value::replaceAllUsesWith(), updateAsyncFuncPointerContextSize(), and llvm::Align::value().
Referenced by doSplitCoroutine().
|
static |
Replace a call to llvm.coro.prepare.retcon.
Definition at line 2189 of file CoroSplit.cpp.
References C(), llvm::dyn_cast(), llvm::Instruction::eraseFromParent(), llvm::CallBase::getArgOperand(), llvm::make_early_inc_range(), llvm::Value::replaceAllUsesWith(), llvm::Value::stripPointerCasts(), and llvm::Value::uses().
Referenced by replaceAllPrepares().
|
static |
Definition at line 629 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), llvm::coro::Async, llvm::cast(), llvm::coro::Shape::CoroSuspends, F, llvm::Value::getType(), llvm::Value::replaceAllUsesWith(), and llvm::coro::Shape::SwiftErrorOps.
Referenced by llvm::coro::BaseCloner::create(), doSplitCoroutine(), and llvm::coro::BaseCloner::replaceSwiftErrorOps().
|
static |
Make resume-clone coro.free conditional on whether the frame is elided.
The destroy slot holds the cleanup clone for an elided frame and the destroy clone for a heap frame. Load it before user code can reentrantly destroy the enclosing caller frame, then use the cached comparison to suppress only the deallocation. The resume clone has already performed the shared coroutine cleanup, so calling either clone here would run that cleanup twice.
Definition at line 185 of file CoroSplit.cpp.
References llvm::applyProfMetadataIfEnabled(), llvm::cast(), Cleanup, llvm::IRBuilderBase::CreateICmpEQ(), llvm::IRBuilderBase::CreateLoad(), llvm::IRBuilderBase::CreatePointerCast(), createSwitchDestroyPtr(), DEBUG_TYPE, llvm::dyn_cast(), FramePtr, llvm::ConstantPointerNull::get(), llvm::Function::getArg(), llvm::Function::getEntryBlock(), llvm::Instruction::getFunction(), llvm::coro::Shape::getSwitchResumePointerType(), llvm::BasicBlock::getTerminator(), llvm::Value::getType(), llvm::Null, llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::Value::replaceAllUsesWith(), and llvm::setExplicitlyUnknownBranchWeightsIfProfiled().
|
static |
Replace an unwind call to llvm.coro.end.
Definition at line 401 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Async, llvm::cast(), llvm::End, FramePtr, markCoroutineAsDone(), maybeFreeRetconStorage(), llvm::LLVMContext::OB_funclet, llvm::coro::Retcon, llvm::coro::RetconOnce, and llvm::coro::Switch.
Referenced by replaceCoroEnd().
|
static |
Definition at line 1329 of file CoroSplit.cpp.
References llvm::UncondBrInst::Create(), llvm::dyn_cast(), llvm::Instruction::eraseFromParent(), llvm::CallBase::getCalledOperand(), llvm::CoroSuspendInst::getCoroSave(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::ilist_node_with_parent< NodeTy, ParentTy, Options >::getPrevNode(), hasCallsBetween(), I, llvm::Value::replaceAllUsesWith(), and llvm::Value::stripPointerCasts().
Referenced by simplifySuspendPoints().
|
static |
Definition at line 1389 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), llvm::cast(), llvm::coro::Shape::CoroBegin, llvm::coro::Shape::CoroSuspends, llvm::coro::Shape::SwitchLoweringStorage::HasFinalSuspend, I, N, simplifySuspendPoint(), std::swap(), llvm::coro::Switch, and llvm::coro::Shape::SwitchLowering.
Referenced by doSplitCoroutine().
|
static |
Definition at line 1171 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), llvm::coro::Async, llvm::coro::Shape::AsyncLoweringStorage::AsyncFuncPointer, llvm::coro::Shape::AsyncLowering, llvm::cast(), llvm::coro::Shape::AsyncLoweringStorage::ContextSize, llvm::ConstantStruct::get(), llvm::GlobalVariable::getInitializer(), and llvm::GlobalVariable::setInitializer().
Referenced by replaceFrameSizeAndAlignment().
|
static |
Definition at line 2138 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::LazyCallGraph::addSplitFunction(), llvm::LazyCallGraph::addSplitRefRecursiveFunctions(), assert(), llvm::coro::Async, C(), llvm::drop_begin(), llvm::SmallVectorTemplateCommon< T, typename >::empty(), FAM, llvm::coro::Shape::SwitchLoweringStorage::HasCoroElideNoAllocVariant, N, postSplitCleanup(), llvm::coro::Retcon, llvm::coro::RetconOnce, llvm::SmallVectorTemplateCommon< T, typename >::size(), llvm::coro::Switch, llvm::coro::Shape::SwitchLowering, llvm::updateCGAndAnalysisManagerForCGSCCPass(), and llvm::updateCGAndAnalysisManagerForFunctionPass().
Referenced by llvm::CoroSplitPass::run().
|
static |
Adjust the scope line of the funclet to the first line number after the suspend point.
This avoids a jump in the line table from the function declaration (where prologue instructions are attributed to) to the suspend point. Only adjust the scope line when the files are the same. If no candidate line number is found, fallback to the line of ActiveSuspend.
Definition at line 894 of file CoroSplit.cpp.
References DL, llvm::Instruction::getDebugLoc(), llvm::DIScope::getFile(), and getFirstNonZeroLocAfterSuspend().
Referenced by llvm::coro::BaseCloner::create().