Example #1
0
static SILFunction *getGlobalGetterFunction(SILOptFunctionBuilder &FunctionBuilder,
                                            SILModule &M,
                                            SILLocation loc,
                                            VarDecl *varDecl) {
  auto getterNameTmp = mangleGetter(varDecl);

  // Check if a getter was generated already.
  if (auto *F = M.lookUpFunction(getterNameTmp))
    return F;

  auto Linkage = (varDecl->getEffectiveAccess() >= AccessLevel::Public
                  ? SILLinkage::PublicNonABI
                  : SILLinkage::Private);
  auto Serialized = (varDecl->getEffectiveAccess() >= AccessLevel::Public
                     ? IsSerialized
                     : IsNotSerialized);

  auto refType = M.Types.getLoweredType(varDecl->getInterfaceType());

  // Function takes no arguments and returns refType
  SILResultInfo Results[] = { SILResultInfo(refType.getASTType(),
                                            ResultConvention::Owned) };
  SILFunctionType::ExtInfo EInfo;
  EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin);
  auto LoweredType =
    SILFunctionType::get(nullptr, EInfo,
                         SILCoroutineKind::None,
                         ParameterConvention::Direct_Unowned,
                         /*params*/ {}, /*yields*/ {}, Results, None,
                         M.getASTContext());
  auto getterName = M.allocateCopy(getterNameTmp);
  return FunctionBuilder.getOrCreateFunction(
      loc, getterName, Linkage, LoweredType, IsBare, IsNotTransparent,
      Serialized, IsNotDynamic);
}
Example #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;
}
Example #3
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;
}