예제 #1
0
파일: GlobalOpt.cpp 프로젝트: adrfer/swift
/// 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;
}
예제 #2
0
파일: GlobalOpt.cpp 프로젝트: apple/swift
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);
}
예제 #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;
}