コード例 #1
0
void FunctionSignatureTransform::ArgumentExplosionFinalizeOptimizedFunction() {
  SILBasicBlock *BB = &*NewF->begin();
  SILBuilder Builder(BB->begin());
  Builder.setCurrentDebugScope(BB->getParent()->getDebugScope());
  unsigned TotalArgIndex = 0;
  for (ArgumentDescriptor &AD : ArgumentDescList) {
    // Simply continue if do not explode.
    if (!AD.Explode) {
      AIM[TotalArgIndex] = AD.Index;
      TotalArgIndex ++;
      continue;
    }

    // OK, we need to explode this argument.
    unsigned ArgOffset = ++TotalArgIndex;
    unsigned OldArgIndex = ArgOffset - 1; 
    llvm::SmallVector<SILValue, 8> LeafValues;

    // We do this in the same order as leaf types since ProjTree expects that the
    // order of leaf values matches the order of leaf types.
    llvm::SmallVector<const ProjectionTreeNode*, 8> LeafNodes;
    AD.ProjTree.getLeafNodes(LeafNodes);
    for (auto Node : LeafNodes) {
      LeafValues.push_back(BB->insertBBArg(ArgOffset++, Node->getType(),
                           BB->getBBArg(OldArgIndex)->getDecl()));
      AIM[TotalArgIndex - 1] = AD.Index;
      TotalArgIndex ++;
    }

    // Then go through the projection tree constructing aggregates and replacing
    // uses.
    AD.ProjTree.replaceValueUsesWithLeafUses(Builder, BB->getParent()->getLocation(),
                                             LeafValues);

    // We ignored debugvalue uses when we constructed the new arguments, in order
    // to preserve as much information as possible, we construct a new value for
    // OrigArg from the leaf values and use that in place of the OrigArg.
    SILValue NewOrigArgValue = AD.ProjTree.computeExplodedArgumentValue(Builder,
                                             BB->getParent()->getLocation(),
                                             LeafValues);

    // Replace all uses of the original arg with the new value.
    SILArgument *OrigArg = BB->getBBArg(OldArgIndex);
    OrigArg->replaceAllUsesWith(NewOrigArgValue);

    // Now erase the old argument since it does not have any uses. We also
    // decrement ArgOffset since we have one less argument now.
    BB->eraseBBArg(OldArgIndex); 
    TotalArgIndex --;
  }
}
コード例 #2
0
SILInstruction *SILCombiner::visitTryApplyInst(TryApplyInst *AI) {
    // apply{partial_apply(x,y)}(z) -> apply(z,x,y) is triggered
    // from visitPartialApplyInst(), so bail here.
    if (isa<PartialApplyInst>(AI->getCallee()))
        return nullptr;

    if (auto *CFI = dyn_cast<ConvertFunctionInst>(AI->getCallee())) {
        return optimizeApplyOfConvertFunctionInst(AI, CFI);
    }

    // Optimize readonly functions with no meaningful users.
    SILFunction *Fn = AI->getReferencedFunction();
    if (Fn && Fn->getEffectsKind() < EffectsKind::ReadWrite) {
        UserListTy Users;
        if (isTryApplyResultNotUsed(Users, AI)) {
            SILBasicBlock *BB = AI->getParent();
            SILBasicBlock *NormalBB = AI->getNormalBB();
            SILBasicBlock *ErrorBB = AI->getErrorBB();
            SILLocation Loc = AI->getLoc();
            Builder.setInsertionPoint(BB);
            Builder.setCurrentDebugScope(AI->getDebugScope());
            eraseApply(AI, Users);

            // Replace the try_apply with a cond_br false, which will be removed by
            // SimplifyCFG. We don't want to modify the CFG in SILCombine.
            auto *TrueLit = Builder.createIntegerLiteral(Loc,
                            SILType::getBuiltinIntegerType(1, Builder.getASTContext()), 0);
            Builder.createCondBranch(Loc, TrueLit, NormalBB, ErrorBB);

            NormalBB->eraseBBArg(0);
            ErrorBB->eraseBBArg(0);
            return nullptr;
        }
        // We found a user that we can't handle.
    }

    // (try_apply (thin_to_thick_function f)) to (try_apply f)
    if (auto *TTTFI = dyn_cast<ThinToThickFunctionInst>(AI->getCallee())) {
        // TODO: Handle substitutions and indirect results
        if (AI->hasSubstitutions() || AI->hasIndirectResults())
            return nullptr;
        SmallVector<SILValue, 4> Arguments;
        for (auto &Op : AI->getArgumentOperands()) {
            Arguments.push_back(Op.get());
        }
        // The type of the substitution is the source type of the thin to thick
        // instruction.
        SILType substTy = TTTFI->getOperand()->getType();
        auto *NewAI = Builder.createTryApply(AI->getLoc(), TTTFI->getOperand(),
                                             substTy,
                                             AI->getSubstitutions(), Arguments,
                                             AI->getNormalBB(), AI->getErrorBB());
        return NewAI;
    }

    // (apply (witness_method)) -> propagate information about
    // a concrete type from init_existential_addr or init_existential_ref.
    if (auto *WMI = dyn_cast<WitnessMethodInst>(AI->getCallee())) {
        propagateConcreteTypeOfInitExistential(AI, WMI);
        return nullptr;
    }

    // (apply (function_ref method_from_protocol_extension)) ->
    // propagate information about a concrete type from init_existential_addr or
    // init_existential_ref.
    if (isa<FunctionRefInst>(AI->getCallee())) {
        if (propagateConcreteTypeOfInitExistential(AI)) {
            return nullptr;
        }
    }

    return nullptr;
}