//===- subzero/src/IceTranslator.cpp - ICE to machine code ------*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the general driver class for translating ICE to
// machine code.
//
//===----------------------------------------------------------------------===//

#include "IceTranslator.h"

#include "IceCfg.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceTargetLowering.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"

#include <iostream>

using namespace Ice;

Translator::~Translator() {}

namespace {
void setValueName(llvm::Value *V, const char *Kind, const IceString &Prefix,
                  uint32_t &NameIndex, Ostream &errs) {
  if (V->hasName()) {
    const std::string &Name(V->getName());
    if (Name.find(Prefix) == 0) {
      errs << "Warning: Default " << Kind << " prefix '" << Prefix
           << "' conflicts with name '" << Name << "'.\n";
    }
    return;
  }
  if (NameIndex == 0) {
    V->setName(Prefix);
    ++NameIndex;
    return;
  }
  std::string Buffer;
  llvm::raw_string_ostream StrBuf(Buffer);
  StrBuf << Prefix << NameIndex;
  V->setName(StrBuf.str());
  ++NameIndex;
}
} // end of anonymous namespace

void Translator::nameUnnamedGlobalAddresses(llvm::Module *Mod) {
  const IceString &GlobalPrefix = Flags.DefaultGlobalPrefix;
  Ostream &errs = Ctx->getStrDump();
  if (!GlobalPrefix.empty()) {
    uint32_t NameIndex = 0;
    for (llvm::Module::global_iterator I = Mod->global_begin(),
                                       E = Mod->global_end();
         I != E; ++I) {
      setValueName(I, "global", GlobalPrefix, NameIndex, errs);
    }
  }
  const IceString &FunctionPrefix = Flags.DefaultFunctionPrefix;
  if (FunctionPrefix.empty())
    return;
  uint32_t NameIndex = 0;
  for (llvm::Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
    setValueName(I, "function", FunctionPrefix, NameIndex, errs);
  }
}

void Translator::translateFcn(Cfg *Fcn) {
  Ctx->resetStats();
  Func.reset(Fcn);
  if (Ctx->getFlags().DisableInternal)
    Func->setInternal(false);
  if (Ctx->getFlags().DisableTranslation) {
    Func->dump();
  } else {
    Timer TTranslate;
    Func->translate();
    if (Ctx->getFlags().SubzeroTimingEnabled) {
      std::cerr << "[Subzero timing] Translate function "
                << Func->getFunctionName() << ": " << TTranslate.getElapsedSec()
                << " sec\n";
    }
    if (Func->hasError()) {
      std::cerr << "ICE translation error: " << Func->getError() << "\n";
      ErrorStatus = true;
    }

    Timer TEmit;
    Func->emit();
    if (Ctx->getFlags().SubzeroTimingEnabled) {
      std::cerr << "[Subzero timing] Emit function " << Func->getFunctionName()
                << ": " << TEmit.getElapsedSec() << " sec\n";
    }
    Ctx->dumpStats(Func->getFunctionName());
  }
}

void Translator::emitConstants() {
  if (!Ctx->getFlags().DisableTranslation && Func)
    Func->getTarget()->emitConstants();
}

void Translator::convertGlobals(llvm::Module *Mod) {
  llvm::OwningPtr<TargetGlobalInitLowering> GlobalLowering(
      TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx));
  for (llvm::Module::const_global_iterator I = Mod->global_begin(),
                                           E = Mod->global_end();
       I != E; ++I) {
    if (!I->hasInitializer())
      continue;
    const llvm::Constant *Initializer = I->getInitializer();
    IceString Name = I->getName();
    unsigned Align = I->getAlignment();
    uint64_t NumElements = 0;
    const char *Data = NULL;
    bool IsInternal = I->hasInternalLinkage();
    bool IsConst = I->isConstant();
    bool IsZeroInitializer = false;

    if (const llvm::ConstantDataArray *CDA =
            llvm::dyn_cast<llvm::ConstantDataArray>(Initializer)) {
      NumElements = CDA->getNumElements();
      assert(llvm::isa<llvm::IntegerType>(CDA->getElementType()) &&
             (llvm::cast<llvm::IntegerType>(CDA->getElementType())
                  ->getBitWidth() == 8));
      Data = CDA->getRawDataValues().data();
    } else if (llvm::isa<llvm::ConstantAggregateZero>(Initializer)) {
      if (const llvm::ArrayType *AT =
              llvm::dyn_cast<llvm::ArrayType>(Initializer->getType())) {
        assert(llvm::isa<llvm::IntegerType>(AT->getElementType()) &&
               (llvm::cast<llvm::IntegerType>(AT->getElementType())
                    ->getBitWidth() == 8));
        NumElements = AT->getNumElements();
        IsZeroInitializer = true;
      } else {
        llvm_unreachable("Unhandled constant aggregate zero type");
      }
    } else {
      llvm_unreachable("Unhandled global initializer");
    }

    GlobalLowering->lower(Name, Align, IsInternal, IsConst, IsZeroInitializer,
                          NumElements, Data,
                          Ctx->getFlags().DisableTranslation);
  }
  GlobalLowering.reset();
}
