コード例 #1
0
ファイル: SILValue.cpp プロジェクト: Daford/swift
ValueOwnershipKind
ValueOwnershipKindVisitor::visitApplyInst(ApplyInst *AI) {
  SILModule &M = AI->getModule();
  bool IsTrivial = AI->getType().isTrivial(M);
  auto Results = AI->getSubstCalleeType()->getDirectResults();
  // No results => empty tuple result => Trivial.
  if (Results.empty() || IsTrivial)
    return ValueOwnershipKind::Trivial;

  // Find the first index where we have a trivial value.
  auto Iter = find_if(Results, [&M](const SILResultInfo &Info) -> bool {
    return Info.getOwnershipKind(M) != ValueOwnershipKind::Trivial;
  });
  // If we have all trivial, then we must be trivial.
  if (Iter == Results.end())
    return ValueOwnershipKind::Trivial;

  unsigned Index = std::distance(Results.begin(), Iter);
  ValueOwnershipKind Base = Results[Index].getOwnershipKind(M);

  for (const SILResultInfo &ResultInfo : Results.slice(Index+1)) {
    auto RKind = ResultInfo.getOwnershipKind(M);
    if (RKind.merge(ValueOwnershipKind::Trivial))
      continue;

    auto MergedValue = Base.merge(RKind.Value);
    if (!MergedValue.hasValue()) {
      llvm_unreachable("Forwarding inst with mismatching ownership kinds?!");
    }
  }

  return Base;
}
コード例 #2
0
ValueOwnershipKind ValueOwnershipKindClassifier::visitApplyInst(ApplyInst *AI) {
  SILModule &M = AI->getModule();
  bool IsTrivial = AI->getType().isTrivial(M);
  SILFunctionConventions fnConv(AI->getSubstCalleeType(), M);
  auto Results = fnConv.getDirectSILResults();
  // No results => empty tuple result => Trivial.
  if (Results.empty() || IsTrivial)
    return ValueOwnershipKind::Trivial;

  CanGenericSignature Sig = AI->getSubstCalleeType()->getGenericSignature();
  // Find the first index where we have a trivial value.
  auto Iter = find_if(Results, [&M, &Sig](const SILResultInfo &Info) -> bool {
    return Info.getOwnershipKind(M, Sig) != ValueOwnershipKind::Trivial;
  });
  // If we have all trivial, then we must be trivial.
  if (Iter == Results.end())
    return ValueOwnershipKind::Trivial;

  ValueOwnershipKind Base = Iter->getOwnershipKind(M, Sig);

  for (const SILResultInfo &ResultInfo :
       SILFunctionConventions::DirectSILResultRange(next(Iter),
                                                    Results.end())) {
    auto RKind = ResultInfo.getOwnershipKind(M, Sig);
    if (RKind.merge(ValueOwnershipKind::Trivial))
      continue;

    auto MergedValue = Base.merge(RKind.Value);
    if (!MergedValue.hasValue()) {
      llvm_unreachable("Forwarding inst with mismatching ownership kinds?!");
    }
  }

  return Base;
}
コード例 #3
0
ファイル: SILOwnershipVerifier.cpp プロジェクト: Daford/swift
OwnershipUseCheckerResult
OwnershipCompatibilityUseChecker::visitForwardingInst(SILInstruction *I) {
  assert(I->getNumOperands() && "Expected to have non-zero operands");
  ArrayRef<Operand> Ops = I->getAllOperands();
  ValueOwnershipKind Base = getOwnershipKind();
  for (const Operand &Op : Ops) {
    auto MergedValue = Base.merge(Op.get().getOwnershipKind());
    if (!MergedValue.hasValue())
      return {false, true};
    Base = MergedValue.getValue();
  }
  return {true, !isAddressOrTrivialType()};
}
コード例 #4
0
// For a forwarding instruction, we loop over all operands and make sure that
// all non-trivial values have the same ownership.
ValueOwnershipKind
ValueOwnershipKindClassifier::visitForwardingInst(SILInstruction *I,
                                                  ArrayRef<Operand> Ops) {
  // A forwarding inst without operands must be trivial.
  if (Ops.empty())
    return ValueOwnershipKind::Trivial;

  // Find the first index where we have a trivial value.
  auto Iter = find_if(Ops, [&I](const Operand &Op) -> bool {
    if (I->isTypeDependentOperand(Op))
      return false;
    return Op.get().getOwnershipKind() != ValueOwnershipKind::Trivial;
  });
  // All trivial.
  if (Iter == Ops.end()) {
    return ValueOwnershipKind::Trivial;
  }

  // See if we have any Any. If we do, just return that for now.
  if (any_of(Ops, [&I](const Operand &Op) -> bool {
        if (I->isTypeDependentOperand(Op))
          return false;
        return Op.get().getOwnershipKind() == ValueOwnershipKind::Any;
      }))
    return ValueOwnershipKind::Any;
  unsigned Index = std::distance(Ops.begin(), Iter);

  ValueOwnershipKind Base = Ops[Index].get().getOwnershipKind();

  for (const Operand &Op : Ops.slice(Index + 1)) {
    if (I->isTypeDependentOperand(Op))
      continue;
    auto OpKind = Op.get().getOwnershipKind();
    if (OpKind.merge(ValueOwnershipKind::Trivial))
      continue;

    auto MergedValue = Base.merge(OpKind.Value);
    if (!MergedValue.hasValue()) {
      // If we have mismatched SILOwnership and sil ownership is not enabled,
      // just return Any for staging purposes. If SILOwnership is enabled, then
      // we must assert!
      if (!I->getModule().getOptions().EnableSILOwnership) {
        return ValueOwnershipKind::Any;
      }
      llvm_unreachable("Forwarding inst with mismatching ownership kinds?!");
    }
  }

  return Base;
}
コード例 #5
0
ファイル: SILOwnershipVerifier.cpp プロジェクト: Daford/swift
OwnershipUseCheckerResult
OwnershipCompatibilityUseChecker::visitReturnInst(ReturnInst *RI) {
  SILModule &M = RI->getModule();
  bool IsTrivial = RI->getOperand()->getType().isTrivial(M);
  auto Results =
      RI->getFunction()->getLoweredFunctionType()->getDirectResults();
  if (Results.empty() || IsTrivial) {
    return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
  }

  // Find the first index where we have a trivial value.
  auto Iter = find_if(Results, [&M](const SILResultInfo &Info) -> bool {
    return Info.getOwnershipKind(M) != ValueOwnershipKind::Trivial;
  });

  // If we have all trivial, then we must be trivial. Why wasn't our original
  // type trivial? This is a hard error since this is a logic error in our code
  // here.
  if (Iter == Results.end())
    llvm_unreachable("Should have already checked a trivial type?!");

  unsigned Index = std::distance(Results.begin(), Iter);
  ValueOwnershipKind Base = Results[Index].getOwnershipKind(M);

  for (const SILResultInfo &ResultInfo : Results.slice(Index + 1)) {
    auto RKind = ResultInfo.getOwnershipKind(M);
    // Ignore trivial types.
    if (RKind.merge(ValueOwnershipKind::Trivial))
      continue;

    auto MergedValue = Base.merge(RKind);
    // If we fail to merge all types in, bail. We can not come up with a proper
    // result type.
    if (!MergedValue.hasValue()) {
      return {false, false};
    }
    // In case Base is Any.
    Base = MergedValue.getValue();
  }

  return {compatibleWithOwnership(Base), true};
}
コード例 #6
0
ファイル: SILValue.cpp プロジェクト: Daford/swift
// For a forwarding instruction, we loop over all operands and make sure that
// all non-trivial values have the same ownership.
ValueOwnershipKind
ValueOwnershipKindVisitor::visitForwardingInst(SILInstruction *I) {
  ArrayRef<Operand> Ops = I->getAllOperands();
  // A forwarding inst without operands must be trivial.
  if (Ops.empty())
    return ValueOwnershipKind::Trivial;

  // Find the first index where we have a trivial value.
  auto Iter =
    find_if(Ops,
            [](const Operand &Op) -> bool {
              return Op.get().getOwnershipKind() != ValueOwnershipKind::Trivial;
            });
  // All trivial.
  if (Iter == Ops.end()) {
    return ValueOwnershipKind::Trivial;
  }

  // See if we have any Any. If we do, just return that for now.
  if (any_of(Ops,
             [](const Operand &Op) -> bool {
               return Op.get().getOwnershipKind() == ValueOwnershipKind::Any;
             }))
    return ValueOwnershipKind::Any;
  unsigned Index = std::distance(Ops.begin(), Iter);

  ValueOwnershipKind Base = Ops[Index].get().getOwnershipKind();

  for (const Operand &Op : Ops.slice(Index+1)) {
    auto OpKind = Op.get().getOwnershipKind();
    if (OpKind.merge(ValueOwnershipKind::Trivial))
      continue;

    auto MergedValue = Base.merge(OpKind.Value);
    if (!MergedValue.hasValue()) {
      llvm_unreachable("Forwarding inst with mismatching ownership kinds?!");
    }
  }

  return Base;
}
コード例 #7
0
ファイル: SILOwnershipVerifier.cpp プロジェクト: Daford/swift
static bool compatibleOwnershipKinds(ValueOwnershipKind K1,
                                     ValueOwnershipKind K2) {
  return K1.merge(K2).hasValue();
}