//===--- SILGlobalVariable.cpp - Defines SILGlobalVariable structure ------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/SILGlobalVariable.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage,
                                             bool IsFragile,
                                             StringRef name,
                                             SILType loweredType,
                                             Optional<SILLocation> loc,
                                             VarDecl *Decl) {
  // Get a StringMapEntry for the variable.  As a sop to error cases,
  // allow the name to have an empty string.
  llvm::StringMapEntry<SILGlobalVariable*> *entry = nullptr;
  if (!name.empty()) {
    entry = &*M.GlobalVariableMap.insert(std::make_pair(name, nullptr)).first;
    assert(!entry->getValue() && "global variable already exists");
    name = entry->getKey();
  }

  auto var = new (M) SILGlobalVariable(M, linkage, IsFragile, name,
                                       loweredType, loc, Decl);

  if (entry) entry->setValue(var);
  return var;
}


SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage,
                                     bool IsFragile,
                                     StringRef Name, SILType LoweredType,
                                     Optional<SILLocation> Loc, VarDecl *Decl)
  : Module(Module),
    Name(Name),
    LoweredType(LoweredType),
    Location(Loc),
    Linkage(unsigned(Linkage)),
    Fragile(IsFragile),
    VDecl(Decl) {
  IsDeclaration = isAvailableExternally(Linkage);
  setLet(Decl ? Decl->isLet() : false);
  InitializerF = nullptr;
  Module.silGlobals.push_back(this);
}

void SILGlobalVariable::setInitializer(SILFunction *InitF) {
  if (InitializerF)
    InitializerF->decrementRefCount();
  // Increment the ref count to make sure it will not be eliminated.
  InitF->incrementRefCount();
  InitializerF = InitF;
}

SILGlobalVariable::~SILGlobalVariable() {
  getModule().GlobalVariableMap.erase(Name);
}

// FIXME

static bool analyzeStaticInitializer(SILFunction *F, SILInstruction *&Val,
                                     SILGlobalVariable *&GVar) {
  Val = nullptr;
  GVar = nullptr;
  // We only handle a single SILBasicBlock for now.
  if (F->size() != 1)
    return false;

  SILBasicBlock *BB = &F->front();
  GlobalAddrInst *SGA = nullptr;
  bool HasStore = false;
  for (auto &I : *BB) {
    // Make sure we have a single GlobalAddrInst and a single StoreInst.
    // And the StoreInst writes to the GlobalAddrInst.
    if (isa<AllocGlobalInst>(&I)) {
      continue;
    } else if (auto *sga = dyn_cast<GlobalAddrInst>(&I)) {
      if (SGA)
        return false;
      SGA = sga;
      GVar = SGA->getReferencedGlobal();
    } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
      if (HasStore || SI->getDest() != SGA)
        return false;
      HasStore = true;
      Val = dyn_cast<SILInstruction>(SI->getSrc());

      // We only handle StructInst and TupleInst being stored to a
      // global variable for now.
      if (!isa<StructInst>(Val) && !isa<TupleInst>(Val))
        return false;
    } else {

      if (auto *bi = dyn_cast<BuiltinInst>(&I)) {
        switch (bi->getBuiltinInfo().ID) {
        case BuiltinValueKind::FPTrunc:
          if (isa<LiteralInst>(bi->getArguments()[0]))
            continue;
          break;
        default:
          return false;
        }
      }

      // Objective-C selector string literals cannot be used in static
      // initializers.
      if (auto *stringLit = dyn_cast<StringLiteralInst>(&I)) {
        switch (stringLit->getEncoding()) {
        case StringLiteralInst::Encoding::UTF8:
        case StringLiteralInst::Encoding::UTF16:
          continue;

        case StringLiteralInst::Encoding::ObjCSelector:
          return false;
        }
      }

      if (I.getKind() != ValueKind::ReturnInst &&
          I.getKind() != ValueKind::StructInst &&
          I.getKind() != ValueKind::TupleInst &&
          I.getKind() != ValueKind::DebugValueInst &&
          I.getKind() != ValueKind::IntegerLiteralInst &&
          I.getKind() != ValueKind::FloatLiteralInst)
        return false;
    }
  }
  return true;
}

bool SILGlobalVariable::canBeStaticInitializer(SILFunction *F) {
  SILInstruction *dummySI;
  SILGlobalVariable *dummyGV;
  return analyzeStaticInitializer(F, dummySI, dummyGV);
}

/// Check if a given SILFunction can be a static initializer. If yes, return
/// the SILGlobalVariable that it writes to.
SILGlobalVariable *SILGlobalVariable::getVariableOfStaticInitializer(
                     SILFunction *F) {
  SILInstruction *dummySI;
  SILGlobalVariable *GV;
  if (analyzeStaticInitializer(F, dummySI, GV))
    return GV;
  return nullptr;
}

/// Return the value that is written into the global variable.
SILInstruction *SILGlobalVariable::getValueOfStaticInitializer() {
  if (!InitializerF)
    return nullptr;

  SILInstruction *SI;
  SILGlobalVariable *dummyGV;
  if (analyzeStaticInitializer(InitializerF, SI, dummyGV))
    return SI;
  return nullptr;
}
