#include "Backend.h"

#include <cassert>
#include <string>
#include <vector>

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"

#include "clang/CodeGen/ModuleBuilder.h"

#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"

#include "llvm/Assembly/PrintModulePass.h"

#include "llvm/Bitcode/ReaderWriter.h"

#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"

#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Metadata.h"

#include "llvm/MC/SubtargetFeature.h"

#include "llvm/Support/Casting.h"
#include "llvm/Support/InstIterator.h"

#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"

namespace ndkpc {

void Backend::CreateFunctionPasses() {
  if (!mpPerFunctionPasses) {
    mpPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
    mpPerFunctionPasses->add(new llvm::TargetData(mpModule));

    // FIXME REMOVE
    //llvm::createStandardFunctionPasses(mpPerFunctionPasses,
    //                                   mCodeGenOpts.OptimizationLevel);
    llvm::PassManagerBuilder PMBuilder;
    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
    PMBuilder.populateFunctionPassManager(*mpPerFunctionPasses);
  }
  return;
}

void Backend::CreateModulePasses() {
  if (!mpPerModulePasses) {
	  mpPerModulePasses = new llvm::PassManager();
	  mpPerModulePasses->add(new llvm::TargetData(mpModule));

	  llvm::PassManagerBuilder PMBuilder;
	  PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
	  PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
	  if (mCodeGenOpts.UnitAtATime) {
		  PMBuilder.DisableUnitAtATime = 0;
	  } else {
		  PMBuilder.DisableUnitAtATime = 1;
	  }

	  if (mCodeGenOpts.UnrollLoops) {
		  PMBuilder.DisableUnrollLoops = 0;
	  } else {
		  PMBuilder.DisableUnrollLoops = 1;
	  }

	  PMBuilder.DisableSimplifyLibCalls = false;
	  PMBuilder.populateModulePassManager(*mpPerModulePasses);
  }
  return;
}

bool Backend::CreateCodeGenPasses() {
  if ((mOT != Compiler::OT_Assembly) && (mOT != Compiler::OT_Object))
    return true;

  // Now we add passes for code emitting
  if (mpCodeGenPasses) {
    return true;
  } else {
    mpCodeGenPasses = new llvm::FunctionPassManager(mpModule);
    mpCodeGenPasses->add(new llvm::TargetData(mpModule));
  }

  // Create the TargetMachine for generating code.
  std::string Triple = mpModule->getTargetTriple();

  std::string Error;
  const llvm::Target* TargetInfo =
      llvm::TargetRegistry::lookupTarget(Triple, Error);
  if (TargetInfo == NULL) {
    mDiags.Report(clang::diag::err_fe_unable_to_create_target) << Error;
    return false;
  }

  llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim;

  // Use hardware FPU.
  //
  // FIXME: Need to detect the CPU capability and decide whether to use softfp.
  // To use softfp, change following 2 lines to
  //
  //  llvm::FloatABIType = llvm::FloatABI::Soft;
  //  llvm::UseSoftFloat = true;
  llvm::FloatABIType = llvm::FloatABI::Hard;
  llvm::UseSoftFloat = false;

  // BCC needs all unknown symbols resolved at compilation time. So we don't
  // need any relocation model.
  llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);


  // This is set for the linker (specify how large of the virtual addresses we
  // can access for all unknown symbols.)
  if (mpModule->getPointerSize() == llvm::Module::Pointer32)
    llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
  else
    // The target may have pointer size greater than 32 (e.g. x86_64
    // architecture) may need large data address model
    llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);

  // Setup feature string
  std::string FeaturesStr;
  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
    llvm::SubtargetFeatures Features;

    for (std::vector<std::string>::const_iterator
             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
         I != E;
         I++)
      Features.AddFeature(*I);

    FeaturesStr = Features.getString();
  }
  llvm::TargetMachine *TM =
      TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr);

  // Register scheduler
  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);

  // Register allocation policy:
  //  createFastRegisterAllocator: fast but bad quality
  //  createLinearScanRegisterAllocator: not so fast but good quality
  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
                                     llvm::createFastRegisterAllocator :
                                     llvm::createLinearScanRegisterAllocator);

  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
  if (mCodeGenOpts.OptimizationLevel == 0)
    OptLevel = llvm::CodeGenOpt::None;
  else if (mCodeGenOpts.OptimizationLevel == 3)
    OptLevel = llvm::CodeGenOpt::Aggressive;

  llvm::TargetMachine::CodeGenFileType CGFT =
      llvm::TargetMachine::CGFT_AssemblyFile;
  if (mOT == Compiler::OT_Object)
    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
  if (TM->addPassesToEmitFile(*mpCodeGenPasses, FormattedOutStream,
                              CGFT, OptLevel)) {
    mDiags.Report(clang::diag::err_fe_unable_to_interface_with_target);
    return false;
  }

  return true;
}

Backend::Backend(const clang::CodeGenOptions &CodeGenOpts,
                 const clang::TargetOptions &TargetOpts,
                 clang::Diagnostic *Diags,
                 llvm::raw_ostream *OS,
                 Compiler::OutputType OT)
    : ASTConsumer(),
      mCodeGenOpts(CodeGenOpts),
      mTargetOpts(TargetOpts),
      mLLVMContext(llvm::getGlobalContext()),
      mDiags(*Diags),
      mpModule(NULL),
      mpOS(OS),
      mOT(OT),
      mpGen(NULL),
      mpPerFunctionPasses(NULL),
      mpPerModulePasses(NULL),
      mpCodeGenPasses(NULL) {
  FormattedOutStream.setStream(*mpOS,
                               llvm::formatted_raw_ostream::PRESERVE_STREAM);
  mpGen = CreateLLVMCodeGen(mDiags, "", mCodeGenOpts, mLLVMContext);
  return;
}

void Backend::Initialize(clang::ASTContext &Ctx) {
  mpGen->Initialize(Ctx);
  mpModule = mpGen->GetModule();
  return;
}

void Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
  mpGen->HandleTopLevelDecl(D);
  return;
}

void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
  mpGen->HandleTranslationUnit(Ctx);

  // Here, we complete a translation unit (whole translation unit is now in LLVM
  // IR). Now, interact with LLVM backend to generate actual machine code (asm
  // or machine code, whatever.)

  // Silently ignore if we weren't initialized for some reason.
  if (!mpModule)
    return;

  llvm::Module *M = mpGen->ReleaseModule();
  if (!M) {
    // The module has been released by IR gen on failures, do not double free.
    mpModule = NULL;
    return;
  }

  assert(mpModule == M &&
              "Unexpected module change during LLVM IR generation");

  // Handle illigal CallSite
  for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
       I != E;
       ++I) {
    for (llvm::inst_iterator i = llvm::inst_begin(*I), e = llvm::inst_end(*I);
         i != e;
         ++i) {
      if (llvm::CallInst* CallInst = llvm::dyn_cast<llvm::CallInst>(&*i)) {
        if (CallInst->isInlineAsm()) {
          // TODO: Should we reflect source location information to diagnostic
          //       class and show to users?
          llvm::errs() << "Inline assembly is illigal. Please don't use it." << "\n";
          exit(1);
        }
      }
    }
  }

  // Create and run per-function passes
  CreateFunctionPasses();
  if (mpPerFunctionPasses) {
    mpPerFunctionPasses->doInitialization();

    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
         I != E;
         I++)
      if (!I->isDeclaration())
        mpPerFunctionPasses->run(*I);

    mpPerFunctionPasses->doFinalization();
  }

  // Create and run module passes
  CreateModulePasses();
  if (mpPerModulePasses)
    mpPerModulePasses->run(*mpModule);

  switch (mOT) {
    case Compiler::OT_Assembly:
    case Compiler::OT_Object: {
      if (!CreateCodeGenPasses())
        return;

      mpCodeGenPasses->doInitialization();

      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
          I != E;
          I++)
        if (!I->isDeclaration())
          mpCodeGenPasses->run(*I);

      mpCodeGenPasses->doFinalization();
      break;
    }
    case Compiler::OT_LLVMAssembly: {
      llvm::PassManager *LLEmitPM = new llvm::PassManager();
      LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream));
      LLEmitPM->run(*mpModule);
      break;
    }
    case Compiler::OT_Bitcode: {
      llvm::PassManager *BCEmitPM = new llvm::PassManager();
      BCEmitPM->add(llvm::createBitcodeWriterPass(FormattedOutStream));
      BCEmitPM->run(*mpModule);
      break;
    }
    case Compiler::OT_Nothing: {
      return;
    }
    default: {
      assert(false && "Unknown output type");
    }
  }

  FormattedOutStream.flush();
  return;
}

void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
  mpGen->HandleTagDeclDefinition(D);
  return;
}

void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
  mpGen->CompleteTentativeDefinition(D);
  return;
}

Backend::~Backend() {
  delete mpModule;
  delete mpGen;
  delete mpPerFunctionPasses;
  delete mpPerModulePasses;
  delete mpCodeGenPasses;
  return;
}

}
