std::string FunctionSignatureInfo::getOptimizedName() const {
  Mangle::Mangler M;
  auto P = SpecializationPass::FunctionSignatureOpts;
  FunctionSignatureSpecializationMangler FSSM(P, M, F);

  // Handle arguments' changes.
  for (unsigned i : indices(ArgDescList)) {
    const ArgumentDescriptor &Arg = ArgDescList[i];
    if (Arg.IsEntirelyDead) {
      FSSM.setArgumentDead(i);
    }

    // If we have an @owned argument and found a callee release for it,
    // convert the argument to guaranteed.
    if (!Arg.CalleeRelease.empty()) {
      FSSM.setArgumentOwnedToGuaranteed(i);
    }

    // If this argument is not dead and we can explode it, add 's' to the
    // mangling.
    if (Arg.Explode && !Arg.IsEntirelyDead) {
      FSSM.setArgumentSROA(i);
    }
  }

  // Handle return value's change.
  // FIXME: handle multiple direct results here
  if (ResultDescList.size() == 1 &&
      !ResultDescList[0].CalleeRetain.empty())
    FSSM.setReturnValueOwnedToUnowned();

  FSSM.mangle();

  return M.finalize();
}
Beispiel #2
0
/// Create a getter function from the initializer function.
static SILFunction *genGetterFromInit(SILFunction *InitF, VarDecl *varDecl) {
  // Generate a getter from the global init function without side-effects.

  Mangle::Mangler getterMangler;
  getterMangler.mangleGlobalGetterEntity(varDecl);
  auto getterName = getterMangler.finalize();

  // Check if a getter was generated already.
  if (auto *F = InitF->getModule().lookUpFunction(getterName))
    return F;

  auto refType = varDecl->getType().getCanonicalTypeOrNull();
  // Function takes no arguments and returns refType
  SILResultInfo ResultInfo(refType, ResultConvention::Owned);
  SILFunctionType::ExtInfo EInfo;
  EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin);
  auto LoweredType = SILFunctionType::get(nullptr, EInfo,
      ParameterConvention::Direct_Owned, { }, ResultInfo, None,
      InitF->getASTContext());
  auto *GetterF = InitF->getModule().getOrCreateFunction(InitF->getLocation(),
     getterName, SILLinkage::PrivateExternal, LoweredType,
      IsBare_t::IsBare, IsTransparent_t::IsNotTransparent,
      IsFragile_t::IsFragile);

  auto *EntryBB = GetterF->createBasicBlock();
  // Copy InitF into GetterF
  BasicBlockCloner Cloner(&*InitF->begin(), EntryBB, /*WithinFunction=*/false);
  Cloner.clone();
  GetterF->setInlined();

  // Find the store instruction
  auto BB = EntryBB;
  SILValue Val;
  SILInstruction *Store;
  for (auto II = BB->begin(), E = BB->end(); II != E;) {
    auto &I = *II++;
    if (isa<AllocGlobalInst>(&I)) {
      I.eraseFromParent();
      continue;
    }

    if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
      Val = SI->getSrc();
      Store = SI;
      continue;
    }

    if (ReturnInst *RI = dyn_cast<ReturnInst>(&I)) {
      SILBuilderWithScope B(RI);
      B.createReturn(RI->getLoc(), Val);
      eraseUsesOfInstruction(RI);
      recursivelyDeleteTriviallyDeadInstructions(RI, true);
      recursivelyDeleteTriviallyDeadInstructions(Store, true);
      return GetterF;
    }
  }
  InitF->getModule().getFunctionList().addNodeToList(GetterF);

  return GetterF;
}
std::string FunctionAnalyzer::getOptimizedName() {
  Mangle::Mangler M;
  auto P = SpecializationPass::FunctionSignatureOpts;
  FunctionSignatureSpecializationMangler FSSM(P, M, F);

  for (unsigned i : indices(ArgDescList)) {
    const ArgumentDescriptor &Arg = ArgDescList[i];
    if (Arg.IsDead) {
      FSSM.setArgumentDead(i);
    }

    // If we have an @owned argument and found a callee release for it,
    // convert the argument to guaranteed.
    if (Arg.CalleeRelease) {
      FSSM.setArgumentOwnedToGuaranteed(i);
    }

    // If this argument is not dead and we can explode it, add 's' to the
    // mangling.
    if (Arg.shouldExplode() && !Arg.IsDead) {
      FSSM.setArgumentSROA(i);
    }
  }

  FSSM.mangle();

  return M.finalize();
}
Beispiel #4
0
  void addDecl(const NominalTypeDecl *decl) {
    auto type = decl->getDeclaredInterfaceType()->getCanonicalType();
    Mangle::Mangler mangler;
    mangler.setModuleContext(decl->getModuleContext());
    mangler.mangleType(type, 0);
    auto mangledName = IGM.getAddrOfStringForTypeRef(mangler.finalize());
    addRelativeAddress(mangledName);

    switch (decl->getKind()) {
    case DeclKind::Class:
    case DeclKind::Struct: {
      auto properties = decl->getStoredProperties();
      addConstantInt32(std::distance(properties.begin(), properties.end()));
      addConstantInt32(fieldRecordSize);
      for (auto property : properties)
        addFieldDecl(property);
      break;
    }
    case DeclKind::Enum: {
      auto enumDecl = cast<EnumDecl>(decl);
      auto cases = enumDecl->getAllElements();
      addConstantInt32(std::distance(cases.begin(), cases.end()));
      addConstantInt32(fieldRecordSize);
      for (auto enumCase : cases)
        addFieldDecl(enumCase);
      break;
    }
    default:
      llvm_unreachable("Not a nominal type");
      break;
    }
  }
Beispiel #5
0
static std::string getClonedName(SILFunction *F,
                                 ParamIndexList &PromotedParamIndices) {
  Mangle::Mangler M;
  auto P = SpecializationPass::AllocBoxToStack;
  FunctionSignatureSpecializationMangler FSSM(P, M, F);
  for (unsigned i : PromotedParamIndices)
    FSSM.setArgumentBoxToStack(i);
  FSSM.mangle();
  return M.finalize();
}
Beispiel #6
0
static std::string mangleGetter(VarDecl *varDecl) {
  Mangle::Mangler getterMangler;
  getterMangler.append("_T");
  getterMangler.mangleGlobalGetterEntity(varDecl);
  std::string Old = getterMangler.finalize();

  NewMangling::ASTMangler NewMangler;
  std::string New = NewMangler.mangleGlobalGetterEntity(varDecl);

  return NewMangling::selectMangling(Old, New);
}
Beispiel #7
0
  void addFieldDecl(const ValueDecl *value) {
    auto type = value->getInterfaceType()->getCanonicalType();
    Mangle::Mangler mangler;
    mangler.setModuleContext(value->getModuleContext());
    mangler.mangleType(type, 0);
    auto mangledName = IGM.getAddrOfStringForTypeRef(mangler.finalize());
    addRelativeAddress(mangledName);

    if (IGM.Opts.StripReflectionNames) {
      addConstantInt32(0);
    } else {
      auto fieldName = IGM.getAddrOfFieldName(value->getNameStr());
      addRelativeAddress(fieldName);
    }
  }
std::string CallSiteDescriptor::createName() const {
  Mangle::Mangler M;
  auto P = SpecializationPass::ClosureSpecializer;
  FunctionSignatureSpecializationMangler FSSM(P, M, getApplyCallee());

  if (auto *PAI = dyn_cast<PartialApplyInst>(getClosure())) {
    FSSM.setArgumentClosureProp(getClosureIndex(), PAI);
    FSSM.mangle();
    return M.finalize();
  }

  auto *TTTFI = cast<ThinToThickFunctionInst>(getClosure());
  FSSM.setArgumentClosureProp(getClosureIndex(), TTTFI);
  FSSM.mangle();
  return M.finalize();
}
std::string CallSiteDescriptor::createName() const {
  Mangle::Mangler M;
  auto P = Demangle::SpecializationPass::ClosureSpecializer;
  FunctionSignatureSpecializationMangler OldFSSM(P, M, isFragile(),
                                                 getApplyCallee());
  NewMangling::FunctionSignatureSpecializationMangler NewFSSM(P, isFragile(),
                                                              getApplyCallee());

  if (auto *PAI = dyn_cast<PartialApplyInst>(getClosure())) {
    OldFSSM.setArgumentClosureProp(getClosureIndex(), PAI);
    NewFSSM.setArgumentClosureProp(getClosureIndex(), PAI);
  } else {
    auto *TTTFI = cast<ThinToThickFunctionInst>(getClosure());
    OldFSSM.setArgumentClosureProp(getClosureIndex(), TTTFI);
    NewFSSM.setArgumentClosureProp(getClosureIndex(), TTTFI);
  }
  OldFSSM.mangle();
  std::string Old = M.finalize();
  std::string New = NewFSSM.mangle();
  return NewMangling::selectMangling(Old, New);
}
GenericFuncSpecializer::GenericFuncSpecializer(SILFunction *GenericFunc,
                                               ArrayRef<Substitution> ParamSubs,
                                               IsFragile_t Fragile,
                                               const ReabstractionInfo &ReInfo)
    : M(GenericFunc->getModule()),
      GenericFunc(GenericFunc),
      ParamSubs(ParamSubs),
      Fragile(Fragile),
      ReInfo(ReInfo) {

  assert(GenericFunc->isDefinition() && "Expected definition to specialize!");

  if (GenericFunc->getContextGenericParams())
    ContextSubs = GenericFunc->getContextGenericParams()
      ->getSubstitutionMap(ParamSubs);

  Mangle::Mangler Mangler;
  GenericSpecializationMangler GenericMangler(Mangler, GenericFunc,
                                              ParamSubs, Fragile);
  GenericMangler.mangle();
  ClonedName = Mangler.finalize();

  DEBUG(llvm::dbgs() << "    Specialized function " << ClonedName << '\n');
}
Beispiel #11
0
/// Generate getter from the initialization code whose
/// result is stored by a given store instruction.
static SILFunction *genGetterFromInit(StoreInst *Store,
                                      SILGlobalVariable *SILG) {
  auto *varDecl = SILG->getDecl();

  Mangle::Mangler getterMangler;
  getterMangler.mangleGlobalGetterEntity(varDecl);
  auto getterName = getterMangler.finalize();

  // Check if a getter was generated already.
  if (auto *F = Store->getModule().lookUpFunction(getterName))
    return F;

  // Find the code that performs the initialization first.
  // Recursively walk the SIL value being assigned to the SILG.

  auto V = Store->getSrc();

  SmallVector<SILInstruction *, 8> ReverseInsns;
  SmallVector<SILInstruction *, 8> Insns;
  ReverseInsns.push_back(Store);
  ReverseInsns.push_back(dyn_cast<SILInstruction>(Store->getDest()));
  if (!analyzeStaticInitializer(V, ReverseInsns))
    return nullptr;

  // Produce a correct order of instructions.
  while (!ReverseInsns.empty()) {
    Insns.push_back(ReverseInsns.pop_back_val());
  }

  // Generate a getter from the global init function without side-effects.
  auto refType = varDecl->getType().getCanonicalTypeOrNull();
  // Function takes no arguments and returns refType
  SILResultInfo ResultInfo(refType, ResultConvention::Owned);
  SILFunctionType::ExtInfo EInfo;
  EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin);
  auto LoweredType = SILFunctionType::get(nullptr, EInfo,
      ParameterConvention::Direct_Owned, { }, ResultInfo, None,
      Store->getModule().getASTContext());
  auto *GetterF = Store->getModule().getOrCreateFunction(Store->getLoc(),
      getterName, SILLinkage::PrivateExternal, LoweredType,
      IsBare_t::IsBare, IsTransparent_t::IsNotTransparent,
      IsFragile_t::IsFragile);
  GetterF->setDebugScope(Store->getFunction()->getDebugScope());
  auto *EntryBB = GetterF->createBasicBlock();
  // Copy instructions into GetterF
  InstructionsCloner Cloner(*GetterF, Insns, EntryBB);
  Cloner.clone();
  GetterF->setInlined();

  // Find the store instruction
  auto BB = EntryBB;
  SILValue Val;
  for (auto &I : *BB) {
    if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
      Val = SI->getSrc();
      SILBuilderWithScope B(SI);
      B.createReturn(SI->getLoc(), Val);
      eraseUsesOfInstruction(SI);
      recursivelyDeleteTriviallyDeadInstructions(SI, true);
      return GetterF;
    }
  }

  Store->getModule().getFunctionList().addNodeToList(GetterF);

  return GetterF;
}
Beispiel #12
0
SILFunction *MaterializeForSetEmitter::createCallback(SILFunction &F, GeneratorFn generator) {
  auto &ctx = SGM.getASTContext();
 
  // Mangle this as if it were a conformance thunk for a closure
  // within the witness.
  std::string name;
  {
    ClosureExpr closure(/*patterns*/ nullptr,
                        /*throws*/ SourceLoc(),
                        /*arrow*/ SourceLoc(),
                        /*in*/ SourceLoc(),
                        /*result*/ TypeLoc(),
                        /*discriminator*/ 0,
                        /*context*/ Witness);
    closure.setType(getMaterializeForSetCallbackType(ctx,
                                 getSelfTypeForCallbackDeclaration(Witness)));
    closure.getCaptureInfo().setGenericParamCaptures(true);

    Mangle::Mangler mangler;
    if (Conformance) {
      mangler.append("_TTW");
      mangler.mangleProtocolConformance(Conformance);
    } else {
      mangler.append("_T");
    }
    mangler.mangleClosureEntity(&closure, /*uncurryLevel=*/1);
    name = mangler.finalize();
  }

  // Get lowered formal types for callback parameters.
  Type selfType = SelfInterfaceType;
  Type selfMetatypeType = MetatypeType::get(SelfInterfaceType,
                                            MetatypeRepresentation::Thick);

  {
    GenericContextScope scope(SGM.Types, GenericSig);

    // If 'self' is a metatype, make it @thin or @thick as needed, but not inside
    // selfMetatypeType.
    if (auto metatype = selfType->getAs<MetatypeType>()) {
      if (!metatype->hasRepresentation())
        selfType = SGM.getLoweredType(metatype).getSwiftRValueType();
    }
  }

  // Create the SILFunctionType for the callback.
  SILParameterInfo params[] = {
    { ctx.TheRawPointerType, ParameterConvention::Direct_Unowned },
    { ctx.TheUnsafeValueBufferType, ParameterConvention::Indirect_Inout },
    { selfType->getCanonicalType(), ParameterConvention::Indirect_Inout },
    { selfMetatypeType->getCanonicalType(), ParameterConvention::Direct_Unowned },
  };
  SILResultInfo result = {
    TupleType::getEmpty(ctx), ResultConvention::Unowned
  };
  auto extInfo = 
    SILFunctionType::ExtInfo()
      .withRepresentation(SILFunctionTypeRepresentation::Thin);

  auto callbackType = SILFunctionType::get(GenericSig, extInfo,
                                /*callee*/ ParameterConvention::Direct_Unowned,
                                           params, result, None, ctx);
  auto callback =
    SGM.M.getOrCreateFunction(Witness, name, Linkage, callbackType,
                              IsBare,
                              F.isTransparent(),
                              F.isFragile());

  callback->setContextGenericParams(GenericParams);
  callback->setDebugScope(new (SGM.M) SILDebugScope(Witness, *callback));

  PrettyStackTraceSILFunction X("silgen materializeForSet callback", callback);
  {
    SILGenFunction gen(SGM, *callback);

    auto makeParam = [&](unsigned index) -> SILArgument* {
      SILType type = gen.F.mapTypeIntoContext(params[index].getSILType());
      return new (SGM.M) SILArgument(gen.F.begin(), type);
    };

    // Add arguments for all the parameters.
    auto valueBuffer = makeParam(0);
    auto storageBuffer = makeParam(1);
    auto self = makeParam(2);
    (void) makeParam(3);

    SILLocation loc = Witness;
    loc.markAutoGenerated();

    // Call the generator function we were provided.
    {
      LexicalScope scope(gen.Cleanups, gen, CleanupLocation::get(loc));
      generator(gen, loc, valueBuffer, storageBuffer, self);
    }

    // Return void.
    auto result = gen.emitEmptyTuple(loc);
    gen.B.createReturn(loc, result);
  }

  callback->verify();
  return callback;
}