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

#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILGlobalVariable.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILLinkage.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage,
                                             IsSerialized_t isSerialized,
                                             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, isSerialized, name,
                                       loweredType, loc, Decl);

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


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

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

/// Get this global variable's fragile attribute.
IsSerialized_t SILGlobalVariable::isSerialized() const {
  return Serialized ? IsSerialized : IsNotSerialized;
}
void SILGlobalVariable::setSerialized(IsSerialized_t isSerialized) {
  assert(isSerialized != IsSerializable);
  Serialized = isSerialized ? 1 : 0;
}

/// Return the value that is written into the global variable.
SILInstruction *SILGlobalVariable::getStaticInitializerValue() {
  if (StaticInitializerBlock.empty())
    return nullptr;

  return &StaticInitializerBlock.back();
}

BuiltinInst *SILGlobalVariable::getOffsetSubtract(const TupleExtractInst *TE,
                                                  SILModule &M) {

  // Match the pattern:
  // tuple_extract(usub_with_overflow(x, integer_literal, integer_literal 0), 0)

  if (TE->getFieldNo() != 0)
    return nullptr;

  auto *BI = dyn_cast<BuiltinInst>(TE->getOperand());
  if (!BI)
    return nullptr;
  if (M.getBuiltinInfo(BI->getName()).ID != BuiltinValueKind::USubOver)
    return nullptr;

  if (!isa<IntegerLiteralInst>(BI->getArguments()[1]))
    return nullptr;

  auto *overflowFlag = dyn_cast<IntegerLiteralInst>(BI->getArguments()[2]);
  if (!overflowFlag || !overflowFlag->getValue().isNullValue())
    return nullptr;

  return BI;
}

bool SILGlobalVariable::isValidStaticInitializerInst(const SILInstruction *I,
                                                     SILModule &M) {
  switch (I->getKind()) {
    case SILInstructionKind::BuiltinInst: {
      auto *bi = cast<BuiltinInst>(I);
      switch (M.getBuiltinInfo(bi->getName()).ID) {
        case BuiltinValueKind::PtrToInt:
          if (isa<LiteralInst>(bi->getArguments()[0]))
            return true;
          break;
        case BuiltinValueKind::StringObjectOr:
          // The first operand can be a string literal (i.e. a pointer), but the
          // second operand must be a constant. This enables creating a
          // a pointer+offset relocation.
          // Note that StringObjectOr requires the or'd bits in the first
          // operand to be 0, so the operation is equivalent to an addition.
          if (isa<IntegerLiteralInst>(bi->getArguments()[1]))
            return true;
          break;
        case BuiltinValueKind::ZExtOrBitCast:
          return true;
        case BuiltinValueKind::USubOver: {
          // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
          // This pattern appears in UTF8 String literal construction.
          auto *TE = bi->getSingleUserOfType<TupleExtractInst>();
          return TE && getOffsetSubtract(TE, M);
        }
        default:
          break;
      }
      return false;
    }
    case SILInstructionKind::TupleExtractInst: {
      // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
      // This pattern appears in UTF8 String literal construction.
      auto *TE = cast<TupleExtractInst>(I);
      if (!getOffsetSubtract(TE, M))
        return false;
      auto *BI = TE->getSingleUserOfType<BuiltinInst>();
      return BI &&
        M.getBuiltinInfo(BI->getName()).ID == BuiltinValueKind::StringObjectOr;
    }
    case SILInstructionKind::StringLiteralInst:
      switch (cast<StringLiteralInst>(I)->getEncoding()) {
        case StringLiteralInst::Encoding::Bytes:
        case StringLiteralInst::Encoding::UTF8:
        case StringLiteralInst::Encoding::UTF16:
          return true;
        case StringLiteralInst::Encoding::ObjCSelector:
          // Objective-C selector string literals cannot be used in static
          // initializers.
          return false;
      }
      return false;
    case SILInstructionKind::StructInst:
    case SILInstructionKind::TupleInst:
    case SILInstructionKind::IntegerLiteralInst:
    case SILInstructionKind::FloatLiteralInst:
    case SILInstructionKind::ObjectInst:
    case SILInstructionKind::ValueToBridgeObjectInst:
      return true;
    default:
      return false;
  }
}

/// Return whether this variable corresponds to a Clang node.
bool SILGlobalVariable::hasClangNode() const {
  return (VDecl ? VDecl->hasClangNode() : false);
}

/// Return the Clang node associated with this variable if it has one.
ClangNode SILGlobalVariable::getClangNode() const {
  return (VDecl ? VDecl->getClangNode() : ClangNode());
}
const clang::Decl *SILGlobalVariable::getClangDecl() const {
  return (VDecl ? VDecl->getClangDecl() : nullptr);
}

//===----------------------------------------------------------------------===//
// Utilities for verification and optimization.
//===----------------------------------------------------------------------===//

static SILGlobalVariable *getStaticallyInitializedVariable(SILFunction *AddrF) {
  if (AddrF->isExternalDeclaration())
    return nullptr;

  auto *RetInst = cast<ReturnInst>(AddrF->findReturnBB()->getTerminator());
  auto *API = dyn_cast<AddressToPointerInst>(RetInst->getOperand());
  if (!API)
    return nullptr;
  auto *GAI = dyn_cast<GlobalAddrInst>(API->getOperand());
  if (!GAI)
    return nullptr;

  return GAI->getReferencedGlobal();
}

SILGlobalVariable *swift::getVariableOfGlobalInit(SILFunction *AddrF) {
  if (!AddrF->isGlobalInit())
    return nullptr;

  if (auto *SILG = getStaticallyInitializedVariable(AddrF))
    return SILG;

  // If the addressor contains a single "once" call, it calls globalinit_func,
  // and the globalinit_func is called by "once" from a single location,
  // continue; otherwise bail.
  BuiltinInst *CallToOnce;
  auto *InitF = findInitializer(&AddrF->getModule(), AddrF, CallToOnce);

  if (!InitF || !InitF->getName().startswith("globalinit_"))
    return nullptr;

  // If the globalinit_func is trivial, continue; otherwise bail.
  SingleValueInstruction *dummyInitVal;
  auto *SILG = getVariableOfStaticInitializer(InitF, dummyInitVal);

  return SILG;
}

SILFunction *swift::getCalleeOfOnceCall(BuiltinInst *BI) {
  assert(BI->getNumOperands() == 2 && "once call should have 2 operands.");

  auto Callee = BI->getOperand(1);
  assert(Callee->getType().castTo<SILFunctionType>()->getRepresentation()
           == SILFunctionTypeRepresentation::CFunctionPointer &&
         "Expected C function representation!");

  if (auto *FR = dyn_cast<FunctionRefInst>(Callee))
    return FR->getReferencedFunction();

  return nullptr;
}

// Find the globalinit_func by analyzing the body of the addressor.
SILFunction *swift::findInitializer(SILModule *Module, SILFunction *AddrF,
                             BuiltinInst *&CallToOnce) {
  // We only handle a single SILBasicBlock for now.
  if (AddrF->size() != 1)
    return nullptr;

  CallToOnce = nullptr;
  SILBasicBlock *BB = &AddrF->front();
  for (auto &I : *BB) {
    // Find the builtin "once" call.
    if (auto *BI = dyn_cast<BuiltinInst>(&I)) {
      const BuiltinInfo &Builtin =
        BI->getModule().getBuiltinInfo(BI->getName());
      if (Builtin.ID != BuiltinValueKind::Once)
        continue;

      // Bail if we have multiple "once" calls in the addressor.
      if (CallToOnce)
        return nullptr;

      CallToOnce = BI;
    }
  }
  if (!CallToOnce)
    return nullptr;
  return getCalleeOfOnceCall(CallToOnce);
}

SILGlobalVariable *
swift::getVariableOfStaticInitializer(SILFunction *InitFunc,
                                      SingleValueInstruction *&InitVal) {
  InitVal = nullptr;
  SILGlobalVariable *GVar = nullptr;
  // We only handle a single SILBasicBlock for now.
  if (InitFunc->size() != 1)
    return nullptr;

  SILBasicBlock *BB = &InitFunc->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) || isa<ReturnInst>(&I)
        || isa<DebugValueInst>(&I)) {
      continue;
    } else if (auto *sga = dyn_cast<GlobalAddrInst>(&I)) {
      if (SGA)
        return nullptr;
      SGA = sga;
      GVar = SGA->getReferencedGlobal();
    } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
      if (HasStore || SI->getDest() != SGA)
        return nullptr;
      HasStore = true;
      SILValue value = SI->getSrc();

      // We only handle StructInst and TupleInst being stored to a
      // global variable for now.
      if (!isa<StructInst>(value) && !isa<TupleInst>(value))
        return nullptr;
      InitVal = cast<SingleValueInstruction>(value);
    } else if (!SILGlobalVariable::isValidStaticInitializerInst(&I,
                                                             I.getModule())) {
      return nullptr;
    }
  }
  if (!InitVal)
    return nullptr;
  return GVar;
}
