LLVM  10.0.0svn
Macros | Typedefs | Enumerations | Functions | Variables
CoroFrame.cpp File Reference
#include "CoroInternal.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/Analysis/PtrUseVisitor.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/circular_raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
Include dependency graph for CoroFrame.cpp:

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "coro-suspend-crossing"
 
#define DEBUG_TYPE   "coro-frame"
 

Typedefs

using SpillInfo = SmallVector< Spill, 8 >
 
typedef SmallPtrSet< BasicBlock *, 8 > VisitedBlocksSet
 

Enumerations

enum  { SmallVectorThreshold = 32 }
 

Functions

static void dump (StringRef Title, SpillInfo const &Spills)
 
static StructTypebuildFrameType (Function &F, coro::Shape &Shape, SpillInfo &Spills)
 
static bool mightWriteIntoAllocaPtr (AllocaInst &A, const DominatorTree &DT, const CoroBeginInst &CB)
 
static InstructionsplitBeforeCatchSwitch (CatchSwitchInst *CatchSwitch)
 
static InstructioninsertSpills (const SpillInfo &Spills, coro::Shape &Shape)
 
static void setUnwindEdgeTo (Instruction *TI, BasicBlock *Succ)
 
static void updatePhiNodes (BasicBlock *DestBB, BasicBlock *OldPred, BasicBlock *NewPred, PHINode *LandingPadReplacement)
 
static BasicBlockehAwareSplitEdge (BasicBlock *BB, BasicBlock *Succ, LandingPadInst *OriginalPad, PHINode *LandingPadReplacement)
 
static void rewritePHIs (BasicBlock &BB)
 
static void rewritePHIs (Function &F)
 
static bool materializable (Instruction &V)
 
static bool isCoroutineStructureIntrinsic (Instruction &I)
 
static void rewriteMaterializableInstructions (IRBuilder<> &IRB, SpillInfo const &Spills)
 
static BasicBlocksplitBlockIfNotFirst (Instruction *I, const Twine &Name)
 
static void splitAround (Instruction *I, const Twine &Name)
 
static bool isSuspendBlock (BasicBlock *BB)
 
static bool isSuspendReachableFrom (BasicBlock *From, VisitedBlocksSet &VisitedOrFreeBBs)
 Does control flow starting at the given block ever reach a suspend instruction before reaching a block in VisitedOrFreeBBs? More...
 
static bool isLocalAlloca (CoroAllocaAllocInst *AI)
 Is the given alloca "local", i.e. More...
 
static bool willLeaveFunctionImmediatelyAfter (BasicBlock *BB, unsigned depth=3)
 After we split the coroutine, will the given basic block be along an obvious exit path for the resumption function? More...
 
static bool localAllocaNeedsStackSave (CoroAllocaAllocInst *AI)
 
static void lowerLocalAllocas (ArrayRef< CoroAllocaAllocInst *> LocalAllocas, SmallVectorImpl< Instruction *> &DeadInsts)
 Turn each of the given local allocas into a normal (dynamic) alloca instruction. More...
 
static InstructionlowerNonLocalAlloca (CoroAllocaAllocInst *AI, coro::Shape &Shape, SmallVectorImpl< Instruction *> &DeadInsts)
 Turn the given coro.alloca.alloc call into a dynamic allocation. More...
 
static ValueemitGetSwiftErrorValue (IRBuilder<> &Builder, Type *ValueTy, coro::Shape &Shape)
 Get the current swifterror value. More...
 
static ValueemitSetSwiftErrorValue (IRBuilder<> &Builder, Value *V, coro::Shape &Shape)
 Set the given value as the current swifterror value. More...
 
static ValueemitSetAndGetSwiftErrorValueAround (Instruction *Call, AllocaInst *Alloca, coro::Shape &Shape)
 Set the swifterror value from the given alloca before a call, then put in back in the alloca afterwards. More...
 
static void eliminateSwiftErrorAlloca (Function &F, AllocaInst *Alloca, coro::Shape &Shape)
 Eliminate a formerly-swifterror alloca by inserting the get/set intrinsics and attempting to MemToReg the alloca away. More...
 
static void eliminateSwiftErrorArgument (Function &F, Argument &Arg, coro::Shape &Shape, SmallVectorImpl< AllocaInst *> &AllocasToPromote)
 "Eliminate" a swifterror argument by reducing it to the alloca case and then loading and storing in the prologue and epilog. More...
 
static void eliminateSwiftError (Function &F, coro::Shape &Shape)
 Eliminate all problematic uses of swifterror arguments and allocas from the function. More...
 

Variables

static const unsigned InvalidFieldIndex = ~0U
 

Macro Definition Documentation

◆ DEBUG_TYPE [1/2]

#define DEBUG_TYPE   "coro-suspend-crossing"

Definition at line 281 of file CoroFrame.cpp.

◆ DEBUG_TYPE [2/2]

#define DEBUG_TYPE   "coro-frame"

Definition at line 281 of file CoroFrame.cpp.

Typedef Documentation

◆ SpillInfo

using SpillInfo = SmallVector<Spill, 8>

Definition at line 319 of file CoroFrame.cpp.

◆ VisitedBlocksSet

Definition at line 1016 of file CoroFrame.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
SmallVectorThreshold 

Definition at line 40 of file CoroFrame.cpp.

Function Documentation

◆ buildFrameType()

static StructType* buildFrameType ( Function F,
coro::Shape Shape,
SpillInfo Spills 
)
static

◆ dump()

static void dump ( StringRef  Title,
SpillInfo const Spills 
)
static

◆ ehAwareSplitEdge()

static BasicBlock* ehAwareSplitEdge ( BasicBlock BB,
BasicBlock Succ,
LandingPadInst OriginalPad,
PHINode LandingPadReplacement 
)
static

◆ eliminateSwiftError()

static void eliminateSwiftError ( Function F,
coro::Shape Shape 
)
static

Eliminate all problematic uses of swifterror arguments and allocas from the function.

We'll fix them up later when splitting the function.

Definition at line 1294 of file CoroFrame.cpp.

References Arg, llvm::Function::args(), llvm::dyn_cast(), eliminateSwiftErrorAlloca(), eliminateSwiftErrorArgument(), llvm::SmallVectorBase::empty(), llvm::Function::getEntryBlock(), llvm::PromoteMemToReg(), llvm::SmallVectorTemplateBase< T >::push_back(), and llvm::AllocaInst::setSwiftError().

Referenced by llvm::coro::buildCoroutineFrame().

◆ eliminateSwiftErrorAlloca()

static void eliminateSwiftErrorAlloca ( Function F,
AllocaInst Alloca,
coro::Shape Shape 
)
static

Eliminate a formerly-swifterror alloca by inserting the get/set intrinsics and attempting to MemToReg the alloca away.

Definition at line 1226 of file CoroFrame.cpp.

References assert(), emitSetAndGetSwiftErrorValueAround(), llvm::Use::getUser(), llvm::isAllocaPromotable(), llvm::Use::set(), llvm::Value::use_begin(), and llvm::Value::use_end().

Referenced by eliminateSwiftError().

◆ eliminateSwiftErrorArgument()

static void eliminateSwiftErrorArgument ( Function F,
Argument Arg,
coro::Shape Shape,
SmallVectorImpl< AllocaInst *> &  AllocasToPromote 
)
static

"Eliminate" a swifterror argument by reducing it to the alloca case and then loading and storing in the prologue and epilog.

The argument keeps the swifterror flag.

Definition at line 1257 of file CoroFrame.cpp.

References llvm::coro::Shape::CoroSuspends, llvm::IRBuilder< T, Inserter >::CreateAlloca(), emitSetAndGetSwiftErrorValueAround(), llvm::Function::getEntryBlock(), llvm::BasicBlock::getFirstNonPHIOrDbg(), llvm::Constant::getNullValue(), llvm::Value::getType(), and llvm::Value::replaceAllUsesWith().

Referenced by eliminateSwiftError().

◆ emitGetSwiftErrorValue()

static Value* emitGetSwiftErrorValue ( IRBuilder<> &  Builder,
Type ValueTy,
coro::Shape Shape 
)
static

◆ emitSetAndGetSwiftErrorValueAround()

static Value* emitSetAndGetSwiftErrorValueAround ( Instruction Call,
AllocaInst Alloca,
coro::Shape Shape 
)
static

Set the swifterror value from the given alloca before a call, then put in back in the alloca afterwards.

Returns an address that will stand in for the swifterror slot until splitting.

Definition at line 1196 of file CoroFrame.cpp.

References llvm::IRBuilder< T, Inserter >::CreateLoad(), llvm::IRBuilder< T, Inserter >::CreateStore(), emitGetSwiftErrorValue(), emitSetSwiftErrorValue(), llvm::AllocaInst::getAllocatedType(), llvm::ilist_node_with_parent< NodeTy, ParentTy, Options >::getNextNode(), and llvm::IRBuilderBase::SetInsertPoint().

Referenced by eliminateSwiftErrorAlloca(), and eliminateSwiftErrorArgument().

◆ emitSetSwiftErrorValue()

static Value* emitSetSwiftErrorValue ( IRBuilder<> &  Builder,
Value V,
coro::Shape Shape 
)
static

Set the given value as the current swifterror value.

Returns a slot that can be used as a swifterror slot.

Definition at line 1178 of file CoroFrame.cpp.

References llvm::IRBuilder< T, Inserter >::CreateCall(), llvm::FunctionType::get(), llvm::ConstantPointerNull::get(), llvm::Type::getPointerTo(), llvm::Value::getType(), and llvm::coro::Shape::SwiftErrorOps.

Referenced by emitSetAndGetSwiftErrorValueAround().

◆ insertSpills()

static Instruction* insertSpills ( const SpillInfo Spills,
coro::Shape Shape 
)
static

◆ isCoroutineStructureIntrinsic()

static bool isCoroutineStructureIntrinsic ( Instruction I)
static

Definition at line 948 of file CoroFrame.cpp.

References I.

Referenced by llvm::coro::buildCoroutineFrame().

◆ isLocalAlloca()

static bool isLocalAlloca ( CoroAllocaAllocInst AI)
static

Is the given alloca "local", i.e.

bounded in lifetime to not cross a suspend point?

Definition at line 1043 of file CoroFrame.cpp.

References llvm::Instruction::getParent(), llvm::SmallPtrSetImpl< PtrType >::insert(), isSuspendReachableFrom(), and llvm::Value::users().

Referenced by llvm::coro::buildCoroutineFrame().

◆ isSuspendBlock()

static bool isSuspendBlock ( BasicBlock BB)
static

◆ isSuspendReachableFrom()

static bool isSuspendReachableFrom ( BasicBlock From,
VisitedBlocksSet VisitedOrFreeBBs 
)
static

Does control flow starting at the given block ever reach a suspend instruction before reaching a block in VisitedOrFreeBBs?

Definition at line 1020 of file CoroFrame.cpp.

References llvm::SmallPtrSetImpl< PtrType >::insert(), isSuspendBlock(), and llvm::successors().

Referenced by isLocalAlloca().

◆ localAllocaNeedsStackSave()

static bool localAllocaNeedsStackSave ( CoroAllocaAllocInst AI)
static

◆ lowerLocalAllocas()

static void lowerLocalAllocas ( ArrayRef< CoroAllocaAllocInst *>  LocalAllocas,
SmallVectorImpl< Instruction *> &  DeadInsts 
)
static

◆ lowerNonLocalAlloca()

static Instruction* lowerNonLocalAlloca ( CoroAllocaAllocInst AI,
coro::Shape Shape,
SmallVectorImpl< Instruction *> &  DeadInsts 
)
static

Turn the given coro.alloca.alloc call into a dynamic allocation.

This happens during the all-instructions iteration, so it must not delete the call.

Definition at line 1138 of file CoroFrame.cpp.

◆ materializable()

static bool materializable ( Instruction V)
static

Definition at line 941 of file CoroFrame.cpp.

Referenced by llvm::coro::buildCoroutineFrame().

◆ mightWriteIntoAllocaPtr()

static bool mightWriteIntoAllocaPtr ( AllocaInst A,
const DominatorTree DT,
const CoroBeginInst CB 
)
static

◆ rewriteMaterializableInstructions()

static void rewriteMaterializableInstructions ( IRBuilder<> &  IRB,
SpillInfo const Spills 
)
static

◆ rewritePHIs() [1/2]

static void rewritePHIs ( BasicBlock BB)
static

◆ rewritePHIs() [2/2]

static void rewritePHIs ( Function F)
static

◆ setUnwindEdgeTo()

static void setUnwindEdgeTo ( Instruction TI,
BasicBlock Succ 
)
static

Definition at line 796 of file CoroFrame.cpp.

References llvm_unreachable.

Referenced by ehAwareSplitEdge().

◆ splitAround()

static void splitAround ( Instruction I,
const Twine Name 
)
static

◆ splitBeforeCatchSwitch()

static Instruction* splitBeforeCatchSwitch ( CatchSwitchInst CatchSwitch)
static

◆ splitBlockIfNotFirst()

static BasicBlock* splitBlockIfNotFirst ( Instruction I,
const Twine Name 
)
static

Definition at line 994 of file CoroFrame.cpp.

References llvm::Instruction::getParent(), I, and llvm::Value::setName().

Referenced by splitAround().

◆ updatePhiNodes()

static void updatePhiNodes ( BasicBlock DestBB,
BasicBlock OldPred,
BasicBlock NewPred,
PHINode LandingPadReplacement 
)
static

◆ willLeaveFunctionImmediatelyAfter()

static bool willLeaveFunctionImmediatelyAfter ( BasicBlock BB,
unsigned  depth = 3 
)
static

After we split the coroutine, will the given basic block be along an obvious exit path for the resumption function?

Definition at line 1057 of file CoroFrame.cpp.

References isSuspendBlock(), and llvm::successors().

Referenced by localAllocaNeedsStackSave().

Variable Documentation

◆ InvalidFieldIndex

const unsigned InvalidFieldIndex = ~0U
static

Definition at line 286 of file CoroFrame.cpp.

Referenced by insertSpills().