• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

C++ SILBasicBlock类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中SILBasicBlock的典型用法代码示例。如果您正苦于以下问题:C++ SILBasicBlock类的具体用法?C++ SILBasicBlock怎么用?C++ SILBasicBlock使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



在下文中一共展示了SILBasicBlock类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: getParent

bool SILArgument::getIncomingValues(llvm::SmallVectorImpl<SILValue> &OutArray) {
  SILBasicBlock *Parent = getParent();

  if (Parent->pred_empty())
    return false;

  unsigned Index = getIndex();
  for (SILBasicBlock *Pred : getParent()->getPreds()) {
    TermInst *TI = Pred->getTerminator();

    if (auto *BI = dyn_cast<BranchInst>(TI)) {
      OutArray.push_back(BI->getArg(Index));
      continue;
    }

    if (auto *CBI = dyn_cast<CondBranchInst>(TI)) {
      OutArray.push_back(CBI->getArgForDestBB(getParent(), this));
      continue;
    }

    if (auto *CCBI = dyn_cast<CheckedCastBranchInst>(TI)) {
      OutArray.push_back(CCBI->getOperand());
      continue;
    }

    if (auto *SWEI = dyn_cast<SwitchEnumInst>(TI)) {
      OutArray.push_back(SWEI->getOperand());
      continue;
    }
    
    return false;
  }

  return true;
}
开发者ID:asdfeng,项目名称:swift,代码行数:35,代码来源:SILArgument.cpp


示例2: while

void ReleaseCodeMotionContext::convergeCodeMotionDataFlow() {
  // Process each basic block with the gen and kill set. Every time the
  // BBSetIn of a basic block changes, the optimization is rerun on its
  // predecessors.
  llvm::SmallVector<SILBasicBlock *, 16> WorkList;
  llvm::SmallPtrSet<SILBasicBlock *, 8> HandledBBs;
  // Push into reverse post order so that we can pop from the back and get
  // post order.
  for (SILBasicBlock *B : PO->getPostOrder()) {
    WorkList.push_back(B);
    HandledBBs.insert(B);
  }
  while (!WorkList.empty()) {
    SILBasicBlock *BB = WorkList.pop_back_val();
    HandledBBs.erase(BB);
    if (processBBWithGenKillSet(BB)) {
      for (auto X : BB->getPredecessorBlocks()) {
        // We do not push basic block into the worklist if its already 
        // in the worklist.
        if (HandledBBs.count(X))
          continue;
        WorkList.push_back(X);
      }
    }
  }
}
开发者ID:yjmeng,项目名称:swift,代码行数:26,代码来源:ARCCodeMotion.cpp


示例3: assert

Condition SILGenFunction::emitCondition(SILValue V, SILLocation Loc,
                                        bool hasFalseCode, bool invertValue,
                                        ArrayRef<SILType> contArgs) {
  assert(B.hasValidInsertionPoint() &&
         "emitting condition at unreachable point");

  SILBasicBlock *ContBB = createBasicBlock();

  for (SILType argTy : contArgs) {
    ContBB->createPHIArgument(argTy, ValueOwnershipKind::Owned);
  }
  
  SILBasicBlock *FalseBB, *FalseDestBB;
  if (hasFalseCode) {
    FalseBB = FalseDestBB = createBasicBlock();
  } else {
    FalseBB = nullptr;
    FalseDestBB = ContBB;
  }

  SILBasicBlock *TrueBB = createBasicBlock();

  if (invertValue)
    B.createCondBranch(Loc, V, FalseDestBB, TrueBB);
  else
    B.createCondBranch(Loc, V, TrueBB, FalseDestBB);
  
  return Condition(TrueBB, FalseBB, ContBB, Loc);
}
开发者ID:Daford,项目名称:swift,代码行数:29,代码来源:SILGenStmt.cpp


示例4: canNRVO

/// Return true if this copy can be eliminated through Named Return Value
/// Optimization (NRVO).
///
/// Simple NRVO cases are handled naturally via backwardPropagateCopy. However,
/// general NRVO is not handled via local propagation without global data
/// flow. Nonetheless, NRVO is a simple pattern that can be detected using a
/// different technique from propagation.
///
/// Example:
/// func nrvo<T : P>(z : Bool) -> T {
///   var rvo : T
///   if (z) {
///     rvo = T(10)
///   }
///   else {
///     rvo = T(1)
///   }
///   return rvo
/// }
///
/// Because of the control flow, backward propagation with a block will fail to
/// find the initializer for the copy at "return rvo". Instead, we directly
/// check for an NRVO pattern by observing a copy in a return block that is the
/// only use of the copy's dest, which must be an @out arg. If there are no
/// instructions between the copy and the return that may write to the copy's
/// source, we simply replace the source's local stack address with the @out
/// address.
///
/// The following SIL pattern will be detected:
///
/// sil @foo : [email protected](thin) <T> (@out T) -> () {
/// bb0(%0 : $*T):
///   %2 = alloc_stack $T
/// ... // arbitrary control flow, but no other uses of %0
/// bbN:
///   copy_addr [take] %2 to [initialization] %0 : $*T
///   ... // no writes
///   return
static bool canNRVO(CopyAddrInst *CopyInst) {
  if (!isa<AllocStackInst>(CopyInst->getSrc()))
    return false;

  // The copy's dest must be an indirect SIL argument. Otherwise, it may not
  // dominate all uses of the source. Worse, it may be aliased. This
  // optimization will early-initialize the copy dest, so we can't allow aliases
  // to be accessed between the initialization and the return.
  auto OutArg = dyn_cast<SILArgument>(CopyInst->getDest());
  if (!OutArg)
    return false;

  auto ArgConv = OutArg->getParameterInfo().getConvention();
  if (ArgConv != ParameterConvention::Indirect_Out)
    return false;

  SILBasicBlock *BB = CopyInst->getParent();
  if (!isa<ReturnInst>(BB->getTerminator()))
    return false;

  SILValue CopyDest = CopyInst->getDest();
  if (!hasOneNonDebugUse(CopyDest))
    return false;

  auto SI = CopyInst->getIterator(), SE = BB->end();
  for (++SI; SI != SE; ++SI) {
    if (SI->mayWriteToMemory() && !isa<DeallocationInst>(SI))
      return false;
  }
  return true;
}
开发者ID:adrfer,项目名称:swift,代码行数:69,代码来源:CopyForwarding.cpp


示例5: LLVM_DEBUG

SILValue
StackAllocationPromoter::getLiveOutValue(BlockSet &PhiBlocks,
                                         SILBasicBlock *StartBB) {
  LLVM_DEBUG(llvm::dbgs() << "*** Searching for a value definition.\n");
  // Walk the Dom tree in search of a defining value:
  for (DomTreeNode *Node = DT->getNode(StartBB); Node; Node = Node->getIDom()) {
    SILBasicBlock *BB = Node->getBlock();

    // If there is a store (that must come after the phi), use its value.
    BlockToInstMap::iterator it = LastStoreInBlock.find(BB);
    if (it != LastStoreInBlock.end())
      if (auto *St = dyn_cast_or_null<StoreInst>(it->second)) {
        LLVM_DEBUG(llvm::dbgs() << "*** Found Store def " << *St->getSrc());
        return St->getSrc();
      }

    // If there is a Phi definition in this block:
    if (PhiBlocks.count(BB)) {
      // Return the dummy instruction that represents the new value that we will
      // add to the basic block.
      SILValue Phi = BB->getArgument(BB->getNumArguments() - 1);
      LLVM_DEBUG(llvm::dbgs() << "*** Found a dummy Phi def " << *Phi);
      return Phi;
    }

    // Move to the next dominating block.
    LLVM_DEBUG(llvm::dbgs() << "*** Walking up the iDOM.\n");
  }
  LLVM_DEBUG(llvm::dbgs() << "*** Could not find a Def. Using Undef.\n");
  return SILUndef::get(ASI->getElementType(), ASI->getModule());
}
开发者ID:DevAndArtist,项目名称:swift,代码行数:31,代码来源:SILMem2Reg.cpp


示例6: OwnedToGuaranteedAddArgumentRelease

/// Set up epilogue work for the thunk arguments based in the given argument.
/// Default implementation simply passes it through.
void
FunctionSignatureTransform::
OwnedToGuaranteedAddArgumentRelease(ArgumentDescriptor &AD, SILBuilder &Builder,
                                    SILFunction *F) {
  // If we have any arguments that were consumed but are now guaranteed,
  // insert a release_value.
  if (!AD.OwnedToGuaranteed) {
    return;
  }

  SILInstruction *Call = findOnlyApply(F);
  if (isa<ApplyInst>(Call)) {
    Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(Call)));
    Builder.createReleaseValue(RegularLocation(SourceLoc()),
                               F->getArguments()[AD.Index],
                               Builder.getDefaultAtomicity());
  } else {
    SILBasicBlock *NormalBB = dyn_cast<TryApplyInst>(Call)->getNormalBB();
    Builder.setInsertionPoint(&*NormalBB->begin());
    Builder.createReleaseValue(RegularLocation(SourceLoc()),
                               F->getArguments()[AD.Index],
                               Builder.getDefaultAtomicity());

    SILBasicBlock *ErrorBB = dyn_cast<TryApplyInst>(Call)->getErrorBB();
    Builder.setInsertionPoint(&*ErrorBB->begin());
    Builder.createReleaseValue(RegularLocation(SourceLoc()),
                               F->getArguments()[AD.Index],
                               Builder.getDefaultAtomicity());
  }
}
开发者ID:herculesjr,项目名称:swift,代码行数:32,代码来源:FunctionSignatureOpts.cpp


示例7: computeForwardingValues

SILValue BBState::computeForwardingValues(RLEContext &Ctx, MemLocation &L,
                                          SILInstruction *InsertPt,
                                          bool UseForwardValOut) {
  SILBasicBlock *ParentBB = InsertPt->getParent();
  bool IsTerminator = (InsertPt == ParentBB->getTerminator());
  // We do not have a SILValue for the current MemLocation, try to construct
  // one.
  //
  // Collect the locations and their corresponding values into a map.
  // First, collect current available locations and their corresponding values
  // into a map.
  MemLocationValueMap Values;
  if (!Ctx.gatherValues(ParentBB, L, Values, UseForwardValOut))
    return SILValue();

  // If the InsertPt is the terminator instruction of the basic block, we
  // *refresh* it as terminator instruction could be deleted as a result
  // of adding new edge values to the terminator instruction.
  if (IsTerminator)
    InsertPt = ParentBB->getTerminator();

  // Second, reduce the available values into a single SILValue we can use to
  // forward.
  SILValue TheForwardingValue;
  TheForwardingValue = MemLocation::reduceWithValues(L, &ParentBB->getModule(),
                                                     Values, InsertPt);
  /// Return the forwarding value.
  return TheForwardingValue;
}
开发者ID:dshah22,项目名称:swift,代码行数:29,代码来源:RedundantLoadElimination.cpp


示例8: initializeAllConsumingUses

void State::initializeAllConsumingUses(
    ArrayRef<BranchPropagatedUser> consumingUses,
    SmallVectorImpl<BrPropUserAndBlockPair> &predsToAddToWorklist) {
  for (BranchPropagatedUser user : consumingUses) {
    SILBasicBlock *userBlock = user.getParent();

    // First initialize our state for the consuming user.
    //
    // If we find another consuming instruction associated with userBlock this
    // will emit a checker error.
    initializeConsumingUse(user, userBlock);

    // Then check if the given block has a use after free and emit an error if
    // we find one.
    checkForSameBlockUseAfterFree(user, userBlock);

    // If this user is in the same block as the value, do not visit
    // predecessors. We must be extra tolerant here since we allow for
    // unreachable code.
    if (userBlock == value->getParentBlock())
      continue;

    // Then for each predecessor of this block...
    for (auto *pred : userBlock->getPredecessorBlocks()) {
      // If this block is not a block that we have already put on the list, add
      // it to the worklist.
      predsToAddToWorklist.push_back({user, pred});
    }
  }
}
开发者ID:DevAndArtist,项目名称:swift,代码行数:30,代码来源:LinearLifetimeChecker.cpp


示例9: while

void RLEContext::processBasicBlocksWithGenKillSet() {
  // Process each basic block with the gen and kill set. Every time the
  // ForwardSetOut of a basic block changes, the optimization is rerun on its
  // successors.
  llvm::SmallVector<SILBasicBlock *, 16> WorkList;
  llvm::DenseSet<SILBasicBlock *> HandledBBs;

  // Push into the worklist in post order so that we can pop from the back and
  // get reverse post order.
  for (SILBasicBlock *BB : PO->getPostOrder()) {
    WorkList.push_back(BB);
    HandledBBs.insert(BB);
  }
  while (!WorkList.empty()) {
    SILBasicBlock *BB = WorkList.pop_back_val();
    HandledBBs.erase(BB);

    // Intersection.
    BlockState &Forwarder = getBlockState(BB);
    // Compute the ForwardSetIn at the beginning of the basic block.
    Forwarder.mergePredecessorAvailSet(*this);

    if (Forwarder.processBasicBlockWithGenKillSet()) {
      for (auto &X : BB->getSuccessors()) {
        // We do not push basic block into the worklist if its already
        // in the worklist.
        if (HandledBBs.find(X) != HandledBBs.end())
          continue;
        WorkList.push_back(X);
      }
    }
  }
}
开发者ID:richlira,项目名称:swift,代码行数:33,代码来源:RedundantLoadElimination.cpp


示例10: emitErrorIsNonNilErrorCheck

/// Perform a foreign error check by testing whether the error was nil.
static void
emitErrorIsNonNilErrorCheck(SILGenFunction &gen, SILLocation loc,
                            ManagedValue errorSlot, bool suppressErrorCheck) {
  // If we're suppressing the check, just don't check.
  if (suppressErrorCheck) return;

  SILValue optionalError = gen.B.emitLoadValueOperation(
      loc, errorSlot.forward(gen), LoadOwnershipQualifier::Take);

  ASTContext &ctx = gen.getASTContext();

  // Switch on the optional error.
  SILBasicBlock *errorBB = gen.createBasicBlock(FunctionSection::Postmatter);
  errorBB->createArgument(optionalError->getType().unwrapAnyOptionalType());
  SILBasicBlock *contBB = gen.createBasicBlock();
  gen.B.createSwitchEnum(loc, optionalError, /*default*/ nullptr,
                         { { ctx.getOptionalSomeDecl(), errorBB },
                           { ctx.getOptionalNoneDecl(), contBB } });

  // Emit the error block. Pass in none for the errorSlot since we have passed
  // in the errorSlot as our BB argument so we can pass ownership correctly. In
  // emitForeignErrorBlock, we will create the appropriate cleanup for the
  // argument.
  gen.emitForeignErrorBlock(loc, errorBB, None);

  // Return the result.
  gen.B.emitBlock(contBB);
  return;
}
开发者ID:yasirmcs,项目名称:swift,代码行数:30,代码来源:SILGenForeignError.cpp


示例11: getParent

SILValue SILArgument::getIncomingValue(unsigned BBIndex) {
  SILBasicBlock *Parent = getParent();

  if (Parent->pred_empty())
    return SILValue();

  unsigned Index = getIndex();

  // We could do an early check if the size of the pred list is <= BBIndex, but
  // that would involve walking the linked list anyways, so we just iterate once
  // over the loop.

  // We use this funky loop since predecessors are stored in a linked list but
  // we want array like semantics.
  unsigned BBCount = 0;
  for (SILBasicBlock *Pred : Parent->getPreds()) {
    // If BBCount is not BBIndex, continue.
    if (BBCount < BBIndex) {
      BBCount++;
      continue;
    }

    // This will return an empty SILValue if we found something we do not
    // understand.
    return getIncomingValueForPred(Parent, Pred, Index);
  }

  return SILValue();
}
开发者ID:ghostbar,项目名称:swift-lang.deb,代码行数:29,代码来源:SILArgument.cpp


示例12: checkSwitchEnumBlockArg

// Given a block argument address base, check if it is actually a box projected
// from a switch_enum. This is a valid pattern at any SIL stage resulting in a
// block-type phi. In later SIL stages, the optimizer may form address-type
// phis, causing this assert if called on those cases.
static void checkSwitchEnumBlockArg(SILPhiArgument *arg) {
  assert(!arg->getType().isAddress());
  SILBasicBlock *Pred = arg->getParent()->getSinglePredecessorBlock();
  if (!Pred || !isa<SwitchEnumInst>(Pred->getTerminator())) {
    arg->dump();
    llvm_unreachable("unexpected box source.");
  }
}
开发者ID:adamnemecek,项目名称:swift,代码行数:12,代码来源:MemAccessUtils.cpp


示例13: new

/// \brief Splits a basic block into two at the specified instruction.
///
/// Note that all the instructions BEFORE the specified iterator
/// stay as part of the original basic block. The old basic block is left
/// without a terminator.
SILBasicBlock *SILBasicBlock::split(iterator I) {
  SILBasicBlock *New =
    new (Parent->getModule()) SILBasicBlock(Parent, this, /*after*/true);
  // Move all of the specified instructions from the original basic block into
  // the new basic block.
  New->InstList.splice(New->end(), InstList, I, end());
  return New;
}
开发者ID:frsoares,项目名称:swift,代码行数:13,代码来源:SILBasicBlock.cpp


示例14: DeadArgumentTransformFunction

void FunctionSignatureTransform::DeadArgumentTransformFunction() {
  SILBasicBlock *BB = &*F->begin();
  for (const ArgumentDescriptor &AD : ArgumentDescList) {
    if (!AD.IsEntirelyDead)
      continue;
    eraseUsesOfValue(BB->getArgument(AD.Index));
  }
}
开发者ID:herculesjr,项目名称:swift,代码行数:8,代码来源:FunctionSignatureOpts.cpp


示例15:

/// getOrEraseBlock - If there are branches to the specified JumpDest,
/// return the block, otherwise return NULL. The JumpDest must be valid.
static SILBasicBlock *getOrEraseBlock(SILGenFunction &SGF, JumpDest &dest) {
  SILBasicBlock *BB = dest.takeBlock();
  if (BB->pred_empty()) {
    // If the block is unused, we don't need it; just delete it.
    SGF.eraseBasicBlock(BB);
    return nullptr;
  }
  return BB;
}
开发者ID:vineetchoudhary,项目名称:swiftforwindows,代码行数:11,代码来源:SILGenStmt.cpp


示例16: DEBUG

bool ARCRegionState::processBlockBottomUp(
    SILBasicBlock &BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
    bool FreezeOwnedArgEpilogueReleases,
    ConsumedArgToEpilogueReleaseMatcher &ConsumedArgToReleaseMap,
    BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap) {
  DEBUG(llvm::dbgs() << ">>>> Bottom Up!\n");

  bool NestingDetected = false;

  BottomUpDataflowRCStateVisitor<ARCRegionState> DataflowVisitor(
      RCIA, *this, FreezeOwnedArgEpilogueReleases, ConsumedArgToReleaseMap,
      IncToDecStateMap);

  // For each non-terminator instruction I in BB visited in reverse...
  for (auto II = std::next(BB.rbegin()), IE = BB.rend(); II != IE;) {
    SILInstruction &I = *II;
    ++II;

    DEBUG(llvm::dbgs() << "VISITING:\n    " << I);

    auto Result = DataflowVisitor.visit(&I);

    // If this instruction can have no further effects on another instructions,
    // continue. This happens for instance if we have cleared all of the state
    // we are tracking.
    if (Result.Kind == RCStateTransitionDataflowResultKind::NoEffects)
      continue;

    // Make sure that we propagate out whether or not nesting was detected.
    NestingDetected |= Result.NestingDetected;

    // This SILValue may be null if we were unable to find a specific RCIdentity
    // that the instruction "visits".
    SILValue Op = Result.RCIdentity;

    auto *InsertPt = &*std::next(SILBasicBlock::iterator(&I));

    // For all other (reference counted value, ref count state) we are
    // tracking...
    for (auto &OtherState : getBottomupStates()) {
      // If the other state's value is blotted, skip it.
      if (!OtherState.hasValue())
        continue;

      // If this is the state associated with the instruction that we are
      // currently visiting, bail.
      if (Op && OtherState->first == Op)
        continue;

      OtherState->second.updateForSameLoopInst(&I, InsertPt, AA);
    }
  }

  return NestingDetected;
}
开发者ID:carriercomm,项目名称:swift,代码行数:55,代码来源:ARCRegionState.cpp


示例17: new

/// \brief Splits a basic block into two at the specified instruction.
///
/// Note that all the instructions BEFORE the specified iterator
/// stay as part of the original basic block. The old basic block is left
/// without a terminator.
SILBasicBlock *SILBasicBlock::splitBasicBlock(iterator I) {
  SILBasicBlock *New = new (Parent->getModule()) SILBasicBlock(Parent);
  SILFunction::iterator Where = std::next(SILFunction::iterator(this));
  SILFunction::iterator First = SILFunction::iterator(New);
  if (Where != First)
    Parent->getBlocks().splice(Where, Parent->getBlocks(), First);
  // Move all of the specified instructions from the original basic block into
  // the new basic block.
  New->InstList.splice(New->end(), InstList, I, end());
  return New;
}
开发者ID:dshah22,项目名称:swift,代码行数:16,代码来源:SILBasicBlock.cpp


示例18: LLVM_DEBUG

/// Optimize placement of initializer calls given a list of calls to the
/// same initializer. All original initialization points must be dominated by
/// the final initialization calls.
///
/// The current heuristic hoists all initialization points within a function to
/// a single dominating call in the outer loop preheader.
void SILGlobalOpt::placeInitializers(SILFunction *InitF,
                                     ArrayRef<ApplyInst *> Calls) {
  LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: calls to "
             << Demangle::demangleSymbolAsString(InitF->getName())
             << " : " << Calls.size() << "\n");
  // Map each initializer-containing function to its final initializer call.
  llvm::DenseMap<SILFunction *, ApplyInst *> ParentFuncs;
  for (auto *AI : Calls) {
    assert(AI->getNumArguments() == 0 && "ill-formed global init call");
    assert(cast<FunctionRefInst>(AI->getCallee())->getReferencedFunction()
           == InitF && "wrong init call");
    SILFunction *ParentF = AI->getFunction();
    DominanceInfo *DT = DA->get(ParentF);
    ApplyInst *HoistAI =
        getHoistedApplyForInitializer(AI, DT, InitF, ParentF, ParentFuncs);

    // If we were unable to find anything, just go onto the next apply.
    if (!HoistAI) {
      continue;
    }

    // Otherwise, move this call to the outermost loop preheader.
    SILBasicBlock *BB = HoistAI->getParent();
    typedef llvm::DomTreeNodeBase<SILBasicBlock> DomTreeNode;
    DomTreeNode *Node = DT->getNode(BB);
    while (Node) {
      SILBasicBlock *DomParentBB = Node->getBlock();
      if (isAvailabilityCheck(DomParentBB)) {
        LLVM_DEBUG(llvm::dbgs() << "  don't hoist above availability check "
                                   "at bb"
                                << DomParentBB->getDebugID() << "\n");
        break;
      }
      BB = DomParentBB;
      if (!isInLoop(BB))
        break;
      Node = Node->getIDom();
    }

    if (BB == HoistAI->getParent()) {
      // BB is either unreachable or not in a loop.
      LLVM_DEBUG(llvm::dbgs() << "  skipping (not in a loop): " << *HoistAI
                              << "  in " << HoistAI->getFunction()->getName()
                              << "\n");
      continue;
    }

    LLVM_DEBUG(llvm::dbgs() << "  hoisting: " << *HoistAI << "  in "
                       << HoistAI->getFunction()->getName() << "\n");
    HoistAI->moveBefore(&*BB->begin());
    placeFuncRef(HoistAI, DT);
    HasChanged = true;
  }
}
开发者ID:phausler,项目名称:swift,代码行数:60,代码来源:GlobalOpt.cpp


示例19: prepareExtraEpilog

static bool prepareExtraEpilog(SILGenFunction &SGF, JumpDest &dest,
                               SILLocation &loc, SILValue *arg) {
  assert(!SGF.B.hasValidInsertionPoint());

  // If we don't have a destination, we don't need to emit the epilog.
  if (!dest.isValid())
    return false;

  // If the destination isn't used, we don't need to emit the epilog.
  SILBasicBlock *epilogBB = dest.getBlock();
  auto pi = epilogBB->pred_begin(), pe = epilogBB->pred_end();
  if (pi == pe) {
    dest = JumpDest::invalid();
    SGF.eraseBasicBlock(epilogBB);
    return false;
  }

  assert(epilogBB->getNumArguments() <= 1);
  assert((epilogBB->getNumArguments() == 1) == (arg != nullptr));
  if (arg) *arg = epilogBB->args_begin()[0];

  bool reposition = true;

  // If the destination has a single branch predecessor,
  // consider emitting the epilog into it.
  SILBasicBlock *predBB = *pi;
  if (++pi == pe) {
    if (auto branch = dyn_cast<BranchInst>(predBB->getTerminator())) {
      assert(branch->getArgs().size() == epilogBB->getNumArguments());

      // Save the location and operand information from the branch,
      // then destroy it.
      loc = branch->getLoc();
      if (arg) *arg = branch->getArgs()[0];
      predBB->erase(branch);

      // Erase the rethrow block.
      SGF.eraseBasicBlock(epilogBB);
      epilogBB = predBB;
      reposition = false;
    }
  }

  // Reposition the block to the end of the postmatter section
  // unless we're emitting into a single predecessor.
  if (reposition) {
    SGF.B.moveBlockTo(epilogBB, SGF.F.end());
  }

  SGF.B.setInsertionPoint(epilogBB);

  return true;
}
开发者ID:DevAndArtist,项目名称:swift,代码行数:53,代码来源:SILGenEpilog.cpp


示例20: replaceBBArgWithStruct

/// At least one value feeding the specified SILArgument is a Struct. Attempt to
/// replace the Argument with a new Struct in the same block.
///
/// When we handle more types of casts, this can become a template.
///
/// ArgValues are the values feeding the specified Argument from each
/// predecessor. They must be listed in order of Arg->getParent()->getPreds().
static StructInst *
replaceBBArgWithStruct(SILPhiArgument *Arg,
                       SmallVectorImpl<SILValue> &ArgValues) {

  SILBasicBlock *PhiBB = Arg->getParent();
  auto *FirstSI = dyn_cast<StructInst>(ArgValues[0]);
  if (!FirstSI)
    return nullptr;

  // Collect the BBArg index of each struct oper.
  // e.g.
  //   struct(A, B)
  //   br (B, A)
  // : ArgIdxForOper => {1, 0}
  SmallVector<unsigned, 4> ArgIdxForOper;
  for (unsigned OperIdx : indices(FirstSI->getElements())) {
    bool FoundMatchingArgIdx = false;
    for (unsigned ArgIdx : indices(PhiBB->getArguments())) {
      SmallVectorImpl<SILValue>::const_iterator AVIter = ArgValues.begin();
      bool TryNextArgIdx = false;
      for (SILBasicBlock *PredBB : PhiBB->getPredecessorBlocks()) {
        // All argument values must be StructInst.
        auto *PredSI = dyn_cast<StructInst>(*AVIter++);
        if (!PredSI)
          return nullptr;
        OperandValueArrayRef EdgeValues =
          getEdgeValuesForTerminator(PredBB->getTerminator(), PhiBB);
        if (EdgeValues[ArgIdx] != PredSI->getElements()[OperIdx]) {
          TryNextArgIdx = true;
          break;
        }
      }
      if (!TryNextArgIdx) {
        assert(AVIter == ArgValues.end() && "# ArgValues does not match # BB preds");
        FoundMatchingArgIdx = true;
        ArgIdxForOper.push_back(ArgIdx);
        break;
      }
    }
    if (!FoundMatchingArgIdx)
      return nullptr;
  }

  SmallVector<SILValue, 4> StructArgs;
  for (auto ArgIdx : ArgIdxForOper)
    StructArgs.push_back(PhiBB->getArgument(ArgIdx));

  SILBuilder Builder(PhiBB, PhiBB->begin());
  return Builder.createStruct(cast<StructInst>(ArgValues[0])->getLoc(),
                              Arg->getType(), StructArgs);
}
开发者ID:uygar,项目名称:swift,代码行数:58,代码来源:SILSSAUpdater.cpp



注:本文中的SILBasicBlock类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ SILBuilder类代码示例发布时间:2022-05-31
下一篇:
C++ SILArgument类代码示例发布时间:2022-05-31
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap