//===- LowerEmuTLS.cpp - Add __emutls_[vt].* variables --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This transformation is required for targets depending on libgcc style
// emulated thread local storage variables. For every defined TLS variable xyz,
// an __emutls_v.xyz is generated. If there is non-zero initialized value
// an __emutls_t.xyz is also generated.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Target/TargetLowering.h"

using namespace llvm;

#define DEBUG_TYPE "loweremutls"

namespace {

class LowerEmuTLS : public ModulePass {
  const TargetMachine *TM;
public:
  static char ID; // Pass identification, replacement for typeid
  explicit LowerEmuTLS() : ModulePass(ID), TM(nullptr) { }
  explicit LowerEmuTLS(const TargetMachine *TM)
      : ModulePass(ID), TM(TM) {
    initializeLowerEmuTLSPass(*PassRegistry::getPassRegistry());
  }
  bool runOnModule(Module &M) override;
private:
  bool addEmuTlsVar(Module &M, const GlobalVariable *GV);
  static void copyLinkageVisibility(Module &M,
                                    const GlobalVariable *from,
                                    GlobalVariable *to) {
    to->setLinkage(from->getLinkage());
    to->setVisibility(from->getVisibility());
    if (from->hasComdat()) {
      to->setComdat(M.getOrInsertComdat(to->getName()));
      to->getComdat()->setSelectionKind(from->getComdat()->getSelectionKind());
    }
  }
};
}

char LowerEmuTLS::ID = 0;

INITIALIZE_PASS(LowerEmuTLS, "loweremutls",
                "Add __emutls_[vt]. variables for emultated TLS model",
                false, false)

ModulePass *llvm::createLowerEmuTLSPass(const TargetMachine *TM) {
  return new LowerEmuTLS(TM);
}

bool LowerEmuTLS::runOnModule(Module &M) {
  if (!TM || !TM->Options.EmulatedTLS)
    return false;

  bool Changed = false;
  SmallVector<const GlobalVariable*, 8> TlsVars;
  for (const auto &G : M.globals()) {
    if (G.isThreadLocal())
      TlsVars.append({&G});
  }
  for (const auto G : TlsVars)
    Changed |= addEmuTlsVar(M, G);
  return Changed;
}

bool LowerEmuTLS::addEmuTlsVar(Module &M, const GlobalVariable *GV) {
  LLVMContext &C = M.getContext();
  PointerType *VoidPtrType = Type::getInt8PtrTy(C);

  std::string EmuTlsVarName = ("__emutls_v." + GV->getName()).str();
  GlobalVariable *EmuTlsVar = M.getNamedGlobal(EmuTlsVarName);
  if (EmuTlsVar)
    return false;  // It has been added before.

  const DataLayout &DL = M.getDataLayout();
  Constant *NullPtr = ConstantPointerNull::get(VoidPtrType);

  // Get non-zero initializer from GV's initializer.
  const Constant *InitValue = nullptr;
  if (GV->hasInitializer()) {
    InitValue = GV->getInitializer();
    const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue);
    // When GV's init value is all 0, omit the EmuTlsTmplVar and let
    // the emutls library function to reset newly allocated TLS variables.
    if (isa<ConstantAggregateZero>(InitValue) ||
        (InitIntValue && InitIntValue->isZero()))
      InitValue = nullptr;
  }

  // Create the __emutls_v. symbol, whose type has 4 fields:
  //     word size;   // size of GV in bytes
  //     word align;  // alignment of GV
  //     void *ptr;   // initialized to 0; set at run time per thread.
  //     void *templ; // 0 or point to __emutls_t.*
  // sizeof(word) should be the same as sizeof(void*) on target.
  IntegerType *WordType = DL.getIntPtrType(C);
  PointerType *InitPtrType = InitValue ?
      PointerType::getUnqual(InitValue->getType()) : VoidPtrType;
  Type *ElementTypes[4] = {WordType, WordType, VoidPtrType, InitPtrType};
  ArrayRef<Type*> ElementTypeArray(ElementTypes, 4);
  StructType *EmuTlsVarType = StructType::create(ElementTypeArray);
  EmuTlsVar = cast<GlobalVariable>(
      M.getOrInsertGlobal(EmuTlsVarName, EmuTlsVarType));
  copyLinkageVisibility(M, GV, EmuTlsVar);

  // Define "__emutls_t.*" and "__emutls_v.*" only if GV is defined.
  if (!GV->hasInitializer())
    return true;

  Type *GVType = GV->getValueType();
  unsigned GVAlignment = GV->getAlignment();
  if (!GVAlignment) {
    // When LLVM IL declares a variable without alignment, use
    // the ABI default alignment for the type.
    GVAlignment = DL.getABITypeAlignment(GVType);
  }

  // Define "__emutls_t.*" if there is InitValue
  GlobalVariable *EmuTlsTmplVar = nullptr;
  if (InitValue) {
    std::string EmuTlsTmplName = ("__emutls_t." + GV->getName()).str();
    EmuTlsTmplVar = dyn_cast_or_null<GlobalVariable>(
        M.getOrInsertGlobal(EmuTlsTmplName, GVType));
    assert(EmuTlsTmplVar && "Failed to create emualted TLS initializer");
    EmuTlsTmplVar->setConstant(true);
    EmuTlsTmplVar->setInitializer(const_cast<Constant*>(InitValue));
    EmuTlsTmplVar->setAlignment(GVAlignment);
    copyLinkageVisibility(M, GV, EmuTlsTmplVar);
  }

  // Define "__emutls_v.*" with initializer and alignment.
  Constant *ElementValues[4] = {
      ConstantInt::get(WordType, DL.getTypeStoreSize(GVType)),
      ConstantInt::get(WordType, GVAlignment),
      NullPtr, EmuTlsTmplVar ? EmuTlsTmplVar : NullPtr
  };
  ArrayRef<Constant*> ElementValueArray(ElementValues, 4);
  EmuTlsVar->setInitializer(
      ConstantStruct::get(EmuTlsVarType, ElementValueArray));
  unsigned MaxAlignment = std::max(
      DL.getABITypeAlignment(WordType),
      DL.getABITypeAlignment(VoidPtrType));
  EmuTlsVar->setAlignment(MaxAlignment);
  return true;
}
