|
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/CallingConv.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 83 of file CoroSplit.cpp.
|
static |
Definition at line 925 of file CoroSplit.cpp.
Referenced by llvm::coro::BaseCloner::create().
|
static |
Definition at line 910 of file CoroSplit.cpp.
References Size.
Referenced by llvm::coro::BaseCloner::create().
|
static |
Definition at line 2242 of file CoroSplit.cpp.
References llvm::SmallVectorTemplateBase< T, bool >::push_back().
Referenced by llvm::CoroSplitPass::run().
|
static |
Definition at line 932 of file CoroSplit.cpp.
Referenced by llvm::coro::BaseCloner::create().
|
static |
Coerce the arguments in FnArgs according to FnTy in CallArgs.
Definition at line 1774 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 688 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 505 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 2251 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 172 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 358 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 2090 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 |
Definition at line 497 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 1228 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 1306 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 1265 of file CoroSplit.cpp.
References I, and llvm::isa().
Referenced by hasCallsBetween(), and hasCallsInBlocksBetween().
|
static |
Definition at line 1277 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 2072 of file CoroSplit.cpp.
References llvm::dyn_cast(), and F.
Referenced by doSplitCoroutine().
|
static |
Definition at line 89 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 154 of file CoroSplit.cpp.
References llvm::coro::Shape::CoroAwaitSuspends, F, and lowerAwaitSuspend().
Referenced by doSplitCoroutine().
|
static |
Definition at line 373 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 160 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 1214 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 2053 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Shape::CoroEnds, llvm::Instruction::eraseFromParent(), llvm::coro::Shape::FramePtr, replaceCoroEnd(), and llvm::coro::Switch.
Referenced by doSplitCoroutine().
|
static |
Definition at line 2064 of file CoroSplit.cpp.
References llvm::coro::Shape::CoroIsInRampInsts, llvm::ConstantInt::getTrue(), and II.
Referenced by doSplitCoroutine().
|
static |
Definition at line 2229 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 1759 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 439 of file CoroSplit.cpp.
References llvm::Instruction::eraseFromParent(), FramePtr, llvm::AnyCoroEndInst::isUnwind(), 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 223 of file CoroSplit.cpp.
References assert(), llvm::cast(), llvm::dyn_cast(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), and llvm::InlineFunction().
Referenced by replaceFallthroughCoroEnd().
|
static |
Replace a non-unwind call to llvm.coro.end.
Definition at line 266 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, assert(), llvm::coro::Async, llvm::cast(), llvm::dyn_cast(), FramePtr, llvm::ConstantPointerNull::get(), llvm::ConstantTokenNone::get(), llvm::PoisonValue::get(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), 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 1190 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Async, llvm::coro::Shape::CoroAligns, llvm::coro::Shape::CoroSizes, llvm::sampleprof::CS, 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 2193 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 630 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 186 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 402 of file CoroSplit.cpp.
References llvm::coro::Shape::ABI, llvm::coro::Async, llvm::cast(), FramePtr, llvm::CallBase::getOperandBundle(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), markCoroutineAsDone(), maybeFreeRetconStorage(), llvm::LLVMContext::OB_funclet, llvm::coro::Retcon, llvm::coro::RetconOnce, and llvm::coro::Switch.
Referenced by replaceCoroEnd().
|
static |
Definition at line 1333 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 1393 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 1175 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 2142 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 863 of file CoroSplit.cpp.
References DL, llvm::dyn_cast_or_null(), llvm::BasicBlock::end(), llvm::Instruction::getDebugLoc(), llvm::DIScope::getFile(), 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::create().