//===----------- Backend.cpp - High-level LLVM backend interface ----------===//
//
// Copyright (C) 2005 to 2013  Chris Lattner, Duncan Sands et al.
//
// This file is part of DragonEgg.
//
// DragonEgg is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2, or (at your option) any later version.
//
// DragonEgg is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// DragonEgg; see the file COPYING.  If not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
//
//===----------------------------------------------------------------------===//
// This file defines the high-level LLVM backend interface.
//===----------------------------------------------------------------------===//

// Plugin headers
#include "dragonegg/Cache.h"
#include "dragonegg/ConstantConversion.h"
#include "dragonegg/Debug.h"
#include "dragonegg/OS.h"
#include "dragonegg/Target.h"
#include "dragonegg/TypeConversion.h"

// LLVM headers
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm-c/Target.h"

#ifdef ENABLE_LLVM_PLUGINS
#include "llvm/LinkAllPasses.h"
#include "llvm/Support/PluginLoader.h"
#endif

// System headers
#include <gmp.h>

// GCC headers
#include "auto-host.h"
#ifndef ENABLE_BUILD_WITH_CXX
#include <cstring> // Otherwise included by system.h with C linkage.
extern "C" {
#endif
#include "config.h"
// Stop GCC declaring 'getopt' as it can clash with the system's declaration.
#undef HAVE_DECL_GETOPT
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"

#include "debug.h"
#include "diagnostic.h"
#include "flags.h"
#include "gcc-plugin.h"
#include "intl.h"
#include "langhooks.h"
#include "output.h"
#include "params.h"
#ifndef DISABLE_VERSION_CHECK
#include "plugin-version.h"
#endif
#include "target.h" // For targetm.
#include "toplev.h"
#include "tree-flow.h"
#include "tree-pass.h"
#include "version.h"

// TODO: In GCC, add targhooks.h to the list of plugin headers and remove this.
tree default_mangle_decl_assembler_name(tree, tree);
#ifndef ENABLE_BUILD_WITH_CXX
} // extern "C"
#endif

// Trees header.
#include "dragonegg/Trees.h"

#if (GCC_MAJOR != 4)
#error Unsupported GCC major version
#endif

using namespace llvm;

// Non-zero if libcalls should not be simplified.
int flag_no_simplify_libcalls;

// Whether -fno-builtin was specified.
// In GCC < 4.6, this variable is only defined in C family front ends.
#if (GCC_MINOR < 6)
extern int flag_no_builtin __attribute__((weak));
#endif

// Non-zero if red-zone is disabled.
//TODOstatic int flag_disable_red_zone = 0;

// Non-zero if implicit floating point instructions are disabled.
//TODOstatic int flag_no_implicit_float = 0;

// LLVM command line arguments specified by the user.
std::vector<std::string> ArgStrings;

/// llvm_asm_file_name - Name of file to use for assembly code output.
static const char *llvm_asm_file_name;

// Global state for the LLVM backend.
Module *TheModule = 0;
DebugInfo *TheDebugInfo = 0;
PassManagerBuilder PassBuilder;
TargetMachine *TheTarget = 0;
TargetFolder *TheFolder = 0;
raw_ostream *OutStream = 0; // Stream to write assembly code to.
formatted_raw_ostream FormattedOutStream;

static bool DebugPassArguments;
static bool DebugPassStructure;
static bool EnableGCCOptimizations;
static bool EmitIR;
static bool EmitObj;
static bool SaveGCCOutput;
static int LLVMCodeGenOptimizeArg = -1;
static int LLVMIROptimizeArg = -1;

std::vector<std::pair<Constant *, int> > StaticCtors, StaticDtors;
SmallSetVector<Constant *, 32> AttributeUsedGlobals;
SmallSetVector<Constant *, 32> AttributeCompilerUsedGlobals;
std::vector<Constant *> AttributeAnnotateGlobals;

/// PerFunctionPasses - This is the list of cleanup passes run per-function
/// as each is compiled.  In cases where we are not doing IPO, it includes the
/// code generator.
static FunctionPassManager *PerFunctionPasses = 0;
static PassManager *PerModulePasses = 0;
static FunctionPassManager *CodeGenPasses = 0;

static void createPerFunctionOptimizationPasses();
static void createPerModuleOptimizationPasses();

// Compatibility hacks for older versions of GCC.
#if (GCC_MINOR < 8)

static struct cgraph_node *cgraph_symbol(struct cgraph_node *N) { return N; }
static struct varpool_node *varpool_symbol(struct varpool_node *N) { return N; }

#define ipa_ref_list_referring_iterate(L,I,P) \
  ipa_ref_list_refering_iterate(L,I,P)
#define ipa_ref_referring_node(R) ipa_ref_refering_node(R)
#define ipa_ref_referring_varpool_node(R) ipa_ref_refering_varpool_node(R)

#define asm_nodes cgraph_asm_nodes
#define asm_node cgraph_asm_node

#define FOR_EACH_FUNCTION(node) \
  for ((node) = cgraph_nodes; (node); (node) = (node)->next)

#define FOR_EACH_VARIABLE(node) \
  for ((node) = varpool_nodes; (node); (node) = (node)->next)

#else

static symtab_node_base *cgraph_symbol(cgraph_node *N) { return &N->symbol; }
static symtab_node_base *varpool_symbol(varpool_node *N) { return &N->symbol; }

#endif

//===----------------------------------------------------------------------===//
//                   Matching LLVM Values with GCC DECL trees
//===----------------------------------------------------------------------===//

/// set_decl_llvm - Remember the LLVM value for a GCC declaration.
Value *set_decl_llvm(tree t, Value *V) {
  assert((isa<CONST_DECL>(t) || HAS_RTL_P(t)) &&
         "Expected a declaration with RTL!");
  assert((!V || isa<GlobalValue>(V)) && "Expected a global value!");
  setCachedValue(t, V);
  return V;
}

/// get_decl_llvm - Retrieve the LLVM value for a GCC declaration, or NULL.
Value *get_decl_llvm(tree t) {
  assert((isa<CONST_DECL>(t) || HAS_RTL_P(t)) &&
         "Expected a declaration with RTL!");
  Value *V = getCachedValue(t);
  return V ? V->stripPointerCasts() : 0;
}

/// changeLLVMConstant - Replace Old with New everywhere, updating all maps
/// (except for AttributeAnnotateGlobals, which is a different kind of animal).
/// At this point we know that New is not in any of these maps.
void changeLLVMConstant(Constant *Old, Constant *New) {
  assert(Old->use_empty() && "Old value has uses!");

  if (AttributeUsedGlobals.count(Old)) {
    AttributeUsedGlobals.remove(Old);
    AttributeUsedGlobals.insert(New);
  }

  if (AttributeCompilerUsedGlobals.count(Old)) {
    AttributeCompilerUsedGlobals.remove(Old);
    AttributeCompilerUsedGlobals.insert(New);
  }

  for (unsigned i = 0, e = StaticCtors.size(); i != e; ++i) {
    if (StaticCtors[i].first == Old)
      StaticCtors[i].first = New;
  }

  for (unsigned i = 0, e = StaticDtors.size(); i != e; ++i) {
    if (StaticDtors[i].first == Old)
      StaticDtors[i].first = New;
  }

  // No need to update the value cache - it autoupdates on RAUW.
}

/// handleVisibility - Forward decl visibility style to global.
void handleVisibility(tree decl, GlobalValue *GV) {
  // If decl has visibility specified explicitely (via attribute) - honour
  // it. Otherwise (e.g. visibility specified via -fvisibility=hidden) honour
  // only if symbol is local.
  if (TREE_PUBLIC(decl) &&
      (DECL_VISIBILITY_SPECIFIED(decl) || !DECL_EXTERNAL(decl))) {
    if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
      GV->setVisibility(GlobalValue::HiddenVisibility);
    else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED)
      GV->setVisibility(GlobalValue::ProtectedVisibility);
    else if (DECL_VISIBILITY(decl) == VISIBILITY_DEFAULT)
      GV->setVisibility(Function::DefaultVisibility);
  }
}

/// CodeGenOptLevel - The optimization level to be used by the code generators.
static CodeGenOpt::Level CodeGenOptLevel() {
  int OptLevel =
      LLVMCodeGenOptimizeArg >= 0 ? LLVMCodeGenOptimizeArg : optimize;
  if (OptLevel <= 0)
    return CodeGenOpt::None;
  if (OptLevel == 1)
    return CodeGenOpt::Less;
  if (OptLevel == 2) // Includes -Os.
    return CodeGenOpt::Default;
  return CodeGenOpt::Aggressive;
}

/// PerFunctionOptLevel - The optimization level to be used by the per-function
/// IR optimizers.
static int PerFunctionOptLevel() {
  // If the user supplied an LLVM optimization level then use it.
  if (LLVMIROptimizeArg >= 0)
    return LLVMIROptimizeArg;
  // Otherwise use the GCC optimization level.
  return optimize;
}

/// ModuleOptLevel - The optimization level to be used by the module level IR
/// optimizers.
static int ModuleOptLevel() {
  // If the user supplied an LLVM optimization level then use it.
  if (LLVMIROptimizeArg >= 0)
    return LLVMIROptimizeArg;
  // If the GCC optimizers were run then tone down the LLVM optimization level:
  //   GCC | LLVM
  //   ----------
  //     0 |   0
  //     1 |   0
  //     2 |   1
  //     3 |   2
  //     4 |   3 (per-module maximum)
  if (EnableGCCOptimizations)
    return optimize > 0 ? optimize - 1 : 0;
  // Otherwise use the GCC optimization level.
  return optimize;
}

#ifndef NDEBUG
// SizeOfGlobalMatchesDecl - Whether the size of the given global value is the
// same as that of the given GCC declaration.  Conservatively returns 'true' if
// the answer is unclear.
static bool SizeOfGlobalMatchesDecl(GlobalValue *GV, tree decl) {
  // If the GCC declaration has no size then nothing useful can be said here.
  if (!DECL_SIZE(decl))
    return true;
  assert(isInt64(DECL_SIZE(decl), true) && "Global decl with variable size!");

  Type *Ty = GV->getType()->getElementType();
  // If the LLVM type has no size then a useful comparison cannot be made.
  if (!Ty->isSized())
    return true;

  // DECL_SIZE need not be a multiple of the alignment, while the LLVM size
  // always is.  Correct for this.
  // TODO: Change getTypeSizeInBits for aggregate types so it is no longer
  // rounded up to the alignment.
  uint64_t gcc_size = getInt64(DECL_SIZE(decl), true);
  const DataLayout *DL = TheTarget->getDataLayout();
  unsigned Align = 8 * DL->getABITypeAlignment(Ty);
  return TheTarget->getDataLayout()->getTypeAllocSizeInBits(Ty) ==
         ((gcc_size + Align - 1) / Align) * Align;
}
#endif

#ifndef LLVM_TARGET_NAME
#error LLVM_TARGET_NAME macro not specified
#endif

/// ConfigureLLVM - Initialized and configure LLVM.
static void ConfigureLLVM(void) {
// Initialize the LLVM backend.
#define DoInit2(TARG, MOD) LLVMInitialize##TARG##MOD()
#define DoInit(T, M) DoInit2(T, M)
  DoInit(LLVM_TARGET_NAME, TargetInfo);
  DoInit(LLVM_TARGET_NAME, Target);
  DoInit(LLVM_TARGET_NAME, TargetMC);
  DoInit(LLVM_TARGET_NAME, AsmPrinter);
  DoInit(LLVM_TARGET_NAME, AsmParser);
#undef DoInit
#undef DoInit2

  // Initialize LLVM command line options.
  std::vector<const char *> Args;
  Args.push_back(progname); // program name

//TODO  // Allow targets to specify PIC options and other stuff to the corresponding
//TODO  // LLVM backends.
//TODO#ifdef LLVM_SET_RED_ZONE_FLAG
//TODO  LLVM_SET_RED_ZONE_FLAG(flag_disable_red_zone)
//TODO#endif
#ifdef LLVM_SET_TARGET_OPTIONS
  LLVM_SET_TARGET_OPTIONS(Args);
#endif
#ifdef LLVM_SET_MACHINE_OPTIONS
  LLVM_SET_MACHINE_OPTIONS(Args);
#endif
  //TODO#ifdef LLVM_SET_IMPLICIT_FLOAT
  //TODO  LLVM_SET_IMPLICIT_FLOAT(flag_no_implicit_float)
  //TODO#endif

  if (time_report || !quiet_flag || flag_detailed_statistics)
    Args.push_back("--time-passes");
  if (!quiet_flag || flag_detailed_statistics)
    Args.push_back("--stats");
  if (flag_verbose_asm)
    Args.push_back("--asm-verbose");
  if (DebugPassStructure)
    Args.push_back("--debug-pass=Structure");
  if (DebugPassArguments)
    Args.push_back("--debug-pass=Arguments");
  if (!flag_schedule_insns)
    Args.push_back("--pre-RA-sched=source");
  if (flag_function_sections)
    Args.push_back("--ffunction-sections");
  if (flag_data_sections)
    Args.push_back("--fdata-sections");

  // If there are options that should be passed through to the LLVM backend
  // directly from the command line, do so now.  This is mainly for debugging
  // purposes, and shouldn't really be for general use.

  //TODO  if (flag_limited_precision > 0) {
  //TODO    std::string Arg("--limit-float-precision="+utostr(flag_limited_precision));
  //TODO    ArgStrings.push_back(Arg);
  //TODO  }

  for (unsigned i = 0, e = ArgStrings.size(); i != e; ++i)
    Args.push_back(ArgStrings[i].c_str());

  //TODO  std::vector<std::string> LLVM_Optns; // Avoid deallocation before opts parsed!
  //TODO  if (llvm_optns) {
  //TODO    llvm::SmallVector<llvm::StringRef, 16> Buf;
  //TODO    SplitString(llvm_optns, Buf);
  //TODO    for(unsigned i = 0, e = Buf.size(); i != e; ++i) {
  //TODO      LLVM_Optns.push_back(Buf[i]);
  //TODO      Args.push_back(LLVM_Optns.back().c_str());
  //TODO    }
  //TODO  }

  Args.push_back(0); // Null terminator.
  int pseudo_argc = Args.size() - 1;
  llvm::cl::ParseCommandLineOptions(pseudo_argc, const_cast<char **>(&Args[0]));
  ArgStrings.clear();
}

/// ComputeTargetTriple - Determine the target triple to use.
static std::string ComputeTargetTriple() {
  // If the target wants to override the architecture, e.g. turning
  // powerpc-darwin-... into powerpc64-darwin-... when -m64 is enabled, do so
  // now.
  std::string TargetTriple = Triple::normalize(TARGET_TRIPLE);
  std::string Components[4]; // Arch-Vendor-OS-Environment
#ifdef LLVM_OVERRIDE_TARGET_ARCH
  Components[0] = LLVM_OVERRIDE_TARGET_ARCH();
#endif
#ifdef LLVM_OVERRIDE_TARGET_VENDOR
  Components[1] = LLVM_OVERRIDE_TARGET_VENDOR();
#endif
#ifdef LLVM_OVERRIDE_TARGET_OS
  Components[2] = LLVM_OVERRIDE_TARGET_OS();
#endif
#ifdef LLVM_OVERRIDE_TARGET_ENVIRONMENT
  Components[3] = LLVM_OVERRIDE_TARGET_ENVIRONMENT();
#endif
  bool Override = false;
  for (unsigned i = 0; i != array_lengthof(Components); ++i)
    if (!Components[i].empty()) {
      Override = true;
      break;
    }
  if (!Override)
    return TargetTriple;

  SmallVector<StringRef, 4> Parts;
  StringRef(TargetTriple).split(Parts, "-");
  for (unsigned i = 0; i != array_lengthof(Components); ++i)
    if (!Components[i].empty()) {
      if (Parts.size() <= i)
        Parts.append(i - Parts.size() + 1, "");
      Parts[i] = Components[i];
    }

  if (Parts.size() == 0)
    return "";
  std::string NewTriple = Parts[0];
  for (unsigned i = 1; i != Parts.size(); ++i)
    NewTriple += (Twine("-") + Parts[i]).str();
  return NewTriple;
}

/// CreateTargetMachine - Create the TargetMachine we will generate code with.
static void CreateTargetMachine(const std::string &TargetTriple) {
  // FIXME: Figure out how to select the target and pass down subtarget info.
  std::string Err;
  const Target *TME = TargetRegistry::lookupTarget(TargetTriple, Err);
  if (!TME)
    report_fatal_error(Err);

  // Figure out the subtarget feature string we pass to the target.
  std::string FeatureStr;
  // The target can set LLVM_SET_SUBTARGET_FEATURES to configure the LLVM
  // backend.
  std::string CPU;
#ifdef LLVM_SET_SUBTARGET_FEATURES
  SubtargetFeatures Features;
  LLVM_SET_SUBTARGET_FEATURES(CPU, Features);
  FeatureStr = Features.getString();
#endif

  // The target can set LLVM_SET_RELOC_MODEL to configure the relocation model
  // used by the LLVM backend.
  Reloc::Model RelocModel = Reloc::Default;
#ifdef LLVM_SET_RELOC_MODEL
  LLVM_SET_RELOC_MODEL(RelocModel);
#endif

  // The target can set LLVM_SET_CODE_MODEL to configure the code model used
  // used by the LLVM backend.
  CodeModel::Model CMModel = CodeModel::Default;
#ifdef LLVM_SET_CODE_MODEL
  LLVM_SET_CODE_MODEL(CMModel);
#endif

  TargetOptions Options;
  if (flag_omit_frame_pointer) {
    // Eliminate frame pointers everywhere.
    Options.NoFramePointerElim = false;
    Options.NoFramePointerElimNonLeaf = false;
  } else {
    // Keep frame pointers everywhere.
    Options.NoFramePointerElim = true;
    Options.NoFramePointerElimNonLeaf = true;
  }
  // If a target has an option to eliminate frame pointers in leaf functions
  // only then it should set
  //   NoFramePointerElim = false;
  //   NoFramePointerElimNonLeaf = true;
  // in its LLVM_SET_TARGET_MACHINE_OPTIONS method when this option is true.
  Options.UnsafeFPMath =
#if (GCC_MINOR > 5)
      fast_math_flags_set_p(&global_options);
#else
  fast_math_flags_set_p();
#endif
  Options.NoInfsFPMath = flag_finite_math_only;
  Options.NoNaNsFPMath = flag_finite_math_only;
  Options.NoZerosInBSS = !flag_zero_initialized_in_bss;
  Options.PositionIndependentExecutable = flag_pie;
#if (GCC_MINOR > 5)
  Options.EnableSegmentedStacks = flag_split_stack;
#endif
#ifdef HAVE_INITFINI_ARRAY
  Options.UseInitArray = true;
#else
  Options.UseInitArray = false;
#endif
  Options.SSPBufferSize = PARAM_VALUE(PARAM_SSP_BUFFER_SIZE);
#ifdef LLVM_SET_TARGET_MACHINE_OPTIONS
  LLVM_SET_TARGET_MACHINE_OPTIONS(Options);
#endif
  TheTarget = TME->createTargetMachine(TargetTriple, CPU, FeatureStr, Options,
                                       RelocModel, CMModel, CodeGenOptLevel());
  assert(TheTarget->getDataLayout()->isBigEndian() == BYTES_BIG_ENDIAN);
  TheTarget->setMCUseCFI(flag_dwarf2_cfi_asm);
  // Binutils does not yet support the use of file directives with an explicit
  // directory.  FIXME: Once GCC learns to detect support for this, condition
  // on what GCC detected.
  TheTarget->setMCUseDwarfDirectory(false);
}

/// output_ident - Insert a .ident directive that identifies the plugin.
static void output_ident(const char *ident_str) {
  const char *ident_asm_op = "\t.ident\t";
#if (GCC_MINOR < 8)
#ifdef IDENT_ASM_OP
  ident_asm_op = IDENT_ASM_OP;
#endif
#endif
  std::string Directive(ident_asm_op);
  Directive += "\"";
  Directive += ident_str;
  Directive += " LLVM: ";
  Directive += LLVM_VERSION;
  Directive += "\"";
  TheModule->setModuleInlineAsm(Directive);
}

/// CreateModule - Create and initialize a module to output LLVM IR to.
static void CreateModule(const std::string &TargetTriple) {
  // Create the module itself.
  StringRef ModuleID = main_input_filename ? main_input_filename : "";
  TheModule = new Module(ModuleID, getGlobalContext());

#if (GCC_MINOR < 8)
#ifdef IDENT_ASM_OP
  if (!flag_no_ident) {
    std::string IdentString;
    const char *pkg_version = "(GNU) ";

    if (strcmp("(GCC) ", pkgversion_string))
      pkg_version = pkgversion_string;

    IdentString += "GCC: ";
    IdentString += pkg_version;
    IdentString += version_string;
    output_ident(IdentString.c_str());
  }
#endif
#endif

  // Install information about the target triple and data layout into the module
  // for optimizer use.
  TheModule->setTargetTriple(TargetTriple);
  TheModule->setDataLayout(
      TheTarget->getDataLayout()->getStringRepresentation());
}

/// flag_default_initialize_globals - Whether global variables with no explicit
/// initial value should be zero initialized.
bool flag_default_initialize_globals = true; // GCC always initializes to zero

/// flag_odr - Whether the language being compiled obeys the One Definition Rule
/// (i.e. if the same function is defined in multiple compilation units, all the
/// definitions are equivalent).
bool flag_odr;

/// flag_functions_from_args - Construct function prototypes from the argument
/// list, ignoring the function type.  This is helpful if the language front-end
/// sometimes creates functions and/or calls where the arguments do not match
/// the arguments given in the function type.
bool flag_functions_from_args;

/// InstallLanguageSettings - Do any language-specific back-end configuration.
static void InstallLanguageSettings() {
  // The principal here is that not doing any language-specific configuration
  // should still result in correct code.  The language-specific settings are
  // only for obtaining better code, by exploiting language-specific features.
  StringRef LanguageName = lang_hooks.name;

  if (LanguageName == "GNU Ada") {
    flag_default_initialize_globals = false; // Uninitialized means what it says
    flag_odr = true; // Ada obeys the one-definition-rule
  } else if (LanguageName == "GNU C") {
    flag_no_simplify_libcalls = flag_no_builtin;
  } else if (LanguageName == "GNU C++") {
    flag_odr = true; // C++ obeys the one-definition-rule
    flag_no_simplify_libcalls = flag_no_builtin;
  } else if (LanguageName == "GNU Fortran") {
    flag_functions_from_args = true;
  } else if (LanguageName == "GNU GIMPLE") { // LTO gold plugin
  } else if (LanguageName == "GNU Go") {
  } else if (LanguageName == "GNU Java") {
  } else if (LanguageName == "GNU Objective-C") {
  } else if (LanguageName == "GNU Objective-C++") {
    flag_odr = true; // Objective C++ obeys the one-definition-rule
  }
}

/// InitializeBackend - Initialize the GCC to LLVM conversion machinery.
/// Can safely be called multiple times.
static void InitializeBackend(void) {
  static bool Initialized = false;
  if (Initialized)
    return;

  // Initialize and configure LLVM.
  ConfigureLLVM();

  // Create the target machine to generate code for.
  const std::string TargetTriple = ComputeTargetTriple();
  CreateTargetMachine(TargetTriple);

  // Create a module to hold the generated LLVM IR.
  CreateModule(TargetTriple);

  TheFolder = new TargetFolder(TheTarget->getDataLayout());

  if (debug_info_level > DINFO_LEVEL_NONE) {
    TheDebugInfo = new DebugInfo(TheModule);
    TheDebugInfo->Initialize();
  }

  // Perform language specific configuration.
  InstallLanguageSettings();

  // Configure the pass builder.
  PassBuilder.SizeLevel = optimize_size;
  PassBuilder.DisableSimplifyLibCalls = flag_no_simplify_libcalls;
  PassBuilder.DisableUnrollLoops = !flag_unroll_loops;
  PassBuilder.DisableUnitAtATime = !flag_unit_at_a_time;
  // FIXME: Hack around the fact the we initialize PassBuilder before processing
  // command line arguments.  The following makes it possible to enable the LLVM
  // vectorizer using -fplugin-arg-dragonegg-llvm-option=-vectorize
  PassBuilder.SLPVectorize = PassManagerBuilder().SLPVectorize;

  PassBuilder.LibraryInfo =
      new TargetLibraryInfo((Triple) TheModule->getTargetTriple());
  if (flag_no_simplify_libcalls)
    PassBuilder.LibraryInfo->disableAllFunctions();

  Initialized = true;
}

/// InitializeOutputStreams - Initialize the assembly code output streams.
static void InitializeOutputStreams(bool Binary) {
  assert(!OutStream && "Output stream already initialized!");
  std::string Error;

  OutStream = new raw_fd_ostream(llvm_asm_file_name, Error,
                                 Binary ? raw_fd_ostream::F_Binary : 0);

  if (!Error.empty())
    report_fatal_error(Error);

  FormattedOutStream.setStream(*OutStream,
                               formatted_raw_ostream::PRESERVE_STREAM);
}

static void createPerFunctionOptimizationPasses() {
  if (PerFunctionPasses)
    return;

  // Create and set up the per-function pass manager.
  // FIXME: Move the code generator to be function-at-a-time.
  PerFunctionPasses = new FunctionPassManager(TheModule);
  PerFunctionPasses->add(new DataLayout(TheModule));

#ifndef NDEBUG
  PerFunctionPasses->add(createVerifierPass());
#endif

  PassBuilder.OptLevel = PerFunctionOptLevel();
  PassBuilder.populateFunctionPassManager(*PerFunctionPasses);

  // If there are no module-level passes that have to be run, we codegen as
  // each function is parsed.
  // FIXME: We can't figure this out until we know there are no always-inline
  // functions.
  // FIXME: This is disabled right now until bugs can be worked out.  Reenable
  // this for fast -O0 compiles!
  if (!EmitIR && 0) {
    FunctionPassManager *PM = PerFunctionPasses;

// Request that addPassesToEmitFile run the Verifier after running
// passes which modify the IR.
#ifndef NDEBUG
    bool DisableVerify = false;
#else
    bool DisableVerify = true;
#endif

    // Normal mode, emit a .s or .o file by running the code generator.
    // Note, this also adds codegenerator level optimization passes.
    InitializeOutputStreams(EmitObj);
    TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
    if (EmitObj)
      CGFT = TargetMachine::CGFT_ObjectFile;
    if (TheTarget->addPassesToEmitFile(*PM, FormattedOutStream, CGFT,
                                       DisableVerify))
      llvm_unreachable("Error interfacing to target machine!");
  }

  PerFunctionPasses->doInitialization();
}

static void createPerModuleOptimizationPasses() {
  if (PerModulePasses)
    return;

  PerModulePasses = new PassManager();
  PerModulePasses->add(new DataLayout(TheModule));
  TheTarget->addAnalysisPasses(*PerModulePasses);

  bool NeedAlwaysInliner = false;
  llvm::Pass *InliningPass = 0;
  if (flag_inline_small_functions && !flag_no_inline) {
    // Inline small functions.  Figure out a reasonable threshold to pass llvm's
    // inliner.  GCC has many options that control inlining, but we have decided
    // not to support anything like that for dragonegg.
    unsigned Threshold;
    if (optimize_size)
      // Reduce inline limit.
      Threshold = 75;
    else if (ModuleOptLevel() >= 3)
      Threshold = 275;
    else
      Threshold = 225;
    InliningPass = createFunctionInliningPass(Threshold);
  } else {
    // If full inliner is not run, check if always-inline is needed to handle
    // functions that are  marked as always_inline.
    // TODO: Consider letting the GCC inliner do this.
    for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;
         ++I)
      if (I->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
                                          Attribute::AlwaysInline)) {
        NeedAlwaysInliner = true;
        break;
      }

    if (NeedAlwaysInliner)
      InliningPass = createAlwaysInlinerPass(); // Inline always_inline funcs
  }

  PassBuilder.OptLevel = ModuleOptLevel();
  PassBuilder.Inliner = InliningPass;
  PassBuilder.populateModulePassManager(*PerModulePasses);

  if (EmitIR) {
    // Emit an LLVM .ll file to the output.  This is used when passed
    // -emit-llvm -S to the GCC driver.
    InitializeOutputStreams(false);
    PerModulePasses->add(createPrintModulePass(OutStream));
  } else {
    // If there are passes we have to run on the entire module, we do codegen
    // as a separate "pass" after that happens.
    // However if there are no module-level passes that have to be run, we
    // codegen as each function is parsed.
    // FIXME: This is disabled right now until bugs can be worked out.  Reenable
    // this for fast -O0 compiles!
    if (PerModulePasses || 1) {
      FunctionPassManager *PM = CodeGenPasses =
          new FunctionPassManager(TheModule);
      PM->add(new DataLayout(*TheTarget->getDataLayout()));
      TheTarget->addAnalysisPasses(*PM);

// Request that addPassesToEmitFile run the Verifier after running
// passes which modify the IR.
#ifndef NDEBUG
      bool DisableVerify = false;
#else
      bool DisableVerify = true;
#endif

      // Normal mode, emit a .s or .o file by running the code generator.
      // Note, this also adds codegenerator level optimization passes.
      InitializeOutputStreams(EmitObj);
      TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
      if (EmitObj)
        CGFT = TargetMachine::CGFT_ObjectFile;
      if (TheTarget->addPassesToEmitFile(*PM, FormattedOutStream, CGFT,
                                         DisableVerify))
        llvm_unreachable("Error interfacing to target machine!");
    }
  }
}

/// ConvertStructorsList - Convert a list of static ctors/dtors to an
/// initializer suitable for the llvm.global_[cd]tors globals.
static void CreateStructorsList(std::vector<std::pair<Constant *, int> > &Tors,
                                const char *Name) {
  std::vector<Constant *> InitList;
  std::vector<Constant *> StructInit;
  StructInit.resize(2);

  LLVMContext &Context = getGlobalContext();

  Type *FPTy =
      FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
  FPTy = FPTy->getPointerTo();

  for (unsigned i = 0, e = Tors.size(); i != e; ++i) {
    StructInit[0] = ConstantInt::get(Type::getInt32Ty(Context), Tors[i].second);

    // __attribute__(constructor) can be on a function with any type.  Make sure
    // the pointer is void()*.
    StructInit[1] = TheFolder->CreateBitCast(Tors[i].first, FPTy);
    InitList.push_back(ConstantStruct::getAnon(Context, StructInit));
  }
  Constant *Array = ConstantArray::get(
      ArrayType::get(InitList[0]->getType(), InitList.size()), InitList);
  new GlobalVariable(*TheModule, Array->getType(), false,
                     GlobalValue::AppendingLinkage, Array, Name);
}

/// ConvertMetadataStringToGV - Convert string to global value. Use existing
/// global if possible.
Constant *ConvertMetadataStringToGV(const char *str) {

  Constant *Init = ConstantDataArray::getString(getGlobalContext(), str);

  // Use cached string if it exists.
  static std::map<Constant *, GlobalVariable *> StringCSTCache;
  GlobalVariable *&Slot = StringCSTCache[Init];
  if (Slot)
    return Slot;

  // Create a new string global.
  GlobalVariable *GV =
      new GlobalVariable(*TheModule, Init->getType(), true,
                         GlobalVariable::PrivateLinkage, Init, ".str");
  GV->setSection("llvm.metadata");
  Slot = GV;
  return GV;

}

/// AddAnnotateAttrsToGlobal - Adds decls that have a annotate attribute to a
/// vector to be emitted later.
void AddAnnotateAttrsToGlobal(GlobalValue *GV, tree decl) {
  LLVMContext &Context = getGlobalContext();

  // Handle annotate attribute on global.
  tree annotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES(decl));
  if (annotateAttr == 0)
    return;

  // Get file and line number
  Constant *lineNo =
      ConstantInt::get(Type::getInt32Ty(Context), DECL_SOURCE_LINE(decl));
  Constant *file = ConvertMetadataStringToGV(DECL_SOURCE_FILE(decl));
  Type *SBP = Type::getInt8PtrTy(Context);
  file = TheFolder->CreateBitCast(file, SBP);

  // There may be multiple annotate attributes. Pass return of lookup_attr
  //  to successive lookups.
  while (annotateAttr) {

    // Each annotate attribute is a tree list.
    // Get value of list which is our linked list of args.
    tree args = TREE_VALUE(annotateAttr);

    // Each annotate attribute may have multiple args.
    // Treat each arg as if it were a separate annotate attribute.
    for (tree a = args; a; a = TREE_CHAIN(a)) {
      // Each element of the arg list is a tree list, so get value
      tree val = TREE_VALUE(a);

      // Assert its a string, and then get that string.
      assert(isa<STRING_CST>(val) &&
             "Annotate attribute arg should always be a string");
      Constant *strGV = AddressOf(val);
      Constant *Element[4] = { TheFolder->CreateBitCast(GV, SBP),
                               TheFolder->CreateBitCast(strGV, SBP), file,
                               lineNo };

      AttributeAnnotateGlobals.push_back(ConstantStruct::getAnon(Element));
    }

    // Get next annotate attribute.
    annotateAttr = TREE_CHAIN(annotateAttr);
    if (annotateAttr)
      annotateAttr = lookup_attribute("annotate", annotateAttr);
  }
}

/// GetLinkageForAlias - The given GCC declaration is an alias.  Return the
/// appropriate LLVM linkage type for it.
static GlobalValue::LinkageTypes GetLinkageForAlias(tree decl) {
  if (DECL_COMDAT(decl))
    // Need not be put out unless needed in this translation unit.
    return GlobalValue::InternalLinkage;

  if (DECL_ONE_ONLY(decl))
    // Copies of this DECL in multiple translation units should be merged.
    return GlobalValue::getWeakLinkage(flag_odr);

  if (DECL_WEAK(decl))
    // The user may have explicitly asked for weak linkage - ignore flag_odr.
    return GlobalValue::WeakAnyLinkage;

  if (!TREE_PUBLIC(decl))
    // Not accessible from outside this translation unit.
    return GlobalValue::InternalLinkage;

  if (DECL_EXTERNAL(decl))
    // Do not allocate storage, and refer to a definition elsewhere.
    return GlobalValue::InternalLinkage;

  return GlobalValue::ExternalLinkage;
}

/// emit_alias - Given decl and target emit alias to target.
static void emit_alias(tree decl, tree target) {
  if (errorcount || sorrycount)
    return; // Do not process broken code.

  // Get or create LLVM global for our alias.
  GlobalValue *V = cast<GlobalValue>(DECL_LLVM(decl));

  while (isa<IDENTIFIER_NODE>(target) && IDENTIFIER_TRANSPARENT_ALIAS(target))
    target = TREE_CHAIN(target);

  if (isa<IDENTIFIER_NODE>(target)) {
    if (struct cgraph_node *fnode = cgraph_node_for_asm(target))
      target = cgraph_symbol(fnode)->decl;
    else if (struct varpool_node *vnode = varpool_node_for_asm(target))
      target = varpool_symbol(vnode)->decl;
  }

  GlobalValue *Aliasee = 0;
  if (isa<IDENTIFIER_NODE>(target)) {
    StringRef AliaseeName(IDENTIFIER_POINTER(target),
                          IDENTIFIER_LENGTH(target));
    if (!lookup_attribute("weakref", DECL_ATTRIBUTES(decl))) {
      Aliasee = TheModule->getNamedValue(AliaseeName);
      if (!Aliasee)
        Aliasee = TheModule->getNamedValue(("\1" + AliaseeName).str());
      if (!Aliasee || Aliasee->hasLocalLinkage()) {
        error("%q+D aliased to undefined symbol %qs", decl,
              AliaseeName.str().c_str());
        return;
      }
    } else {
      // weakref to external symbol.
      if (GlobalVariable *GV = llvm::dyn_cast<GlobalVariable>(V))
        Aliasee = new GlobalVariable(
            *TheModule, GV->getType()->getElementType(), GV->isConstant(),
            GlobalVariable::ExternalWeakLinkage, NULL, AliaseeName);
      else if (Function *F = llvm::dyn_cast<Function>(V))
        Aliasee = Function::Create(F->getFunctionType(),
                                   Function::ExternalWeakLinkage, AliaseeName,
                                   TheModule);
      else
        llvm_unreachable("Unsuported global value");
    }
  } else {
    Aliasee = cast<GlobalValue>(DEFINITION_LLVM(target));
  }

  GlobalValue::LinkageTypes Linkage = GetLinkageForAlias(decl);

  if (Linkage != GlobalValue::InternalLinkage) {
    // Create the LLVM alias.
    GlobalAlias *GA =
        new GlobalAlias(Aliasee->getType(), Linkage, "", Aliasee, TheModule);
    handleVisibility(decl, GA);

    // Associate it with decl instead of V.
    V->replaceAllUsesWith(ConstantExpr::getBitCast(GA, V->getType()));
    changeLLVMConstant(V, GA);
    GA->takeName(V);
  } else {
    // Make all users of the alias directly use the aliasee instead.
    V->replaceAllUsesWith(ConstantExpr::getBitCast(Aliasee, V->getType()));
    changeLLVMConstant(V, Aliasee);
  }

  V->eraseFromParent();

  // Mark the alias as written so gcc doesn't waste time outputting it.
  TREE_ASM_WRITTEN(decl) = 1;
}

/// emit_varpool_aliases - Output any aliases associated with the given varpool
/// node.
static void emit_varpool_aliases(struct varpool_node *node) {
#if (GCC_MINOR < 7)
  for (struct varpool_node *alias = node->extra_name; alias;
       alias = alias->next)
    emit_alias(alias->decl, node->decl);
#else
  struct ipa_ref *ref;
  for (int i = 0;
       ipa_ref_list_referring_iterate(&varpool_symbol(node)->ref_list, i, ref);
       i++)
    if (ref->use == IPA_REF_ALIAS) {
      struct varpool_node *alias = ipa_ref_referring_varpool_node(ref);
      emit_alias(varpool_symbol(alias)->decl, alias->alias_of);
      emit_varpool_aliases(alias);
    }
#endif
}

/// emit_global - Emit the specified VAR_DECL or aggregate CONST_DECL to LLVM as
/// a global variable.  This function implements the end of assemble_variable.
static void emit_global(tree decl) {
  // FIXME: DECL_PRESERVE_P indicates the var is marked with attribute 'used'.

  // Global register variables don't turn into LLVM GlobalVariables.
  if (isa<VAR_DECL>(decl) && DECL_REGISTER(decl))
    return;

  // If we encounter a forward declaration then do not emit the global yet.
  if (!TYPE_SIZE(TREE_TYPE(decl)))
    return;

  //TODO  timevar_push(TV_LLVM_GLOBALS);

  // Get or create the global variable now.
  GlobalVariable *GV = cast<GlobalVariable>(DECL_LLVM(decl));

  // Convert the initializer over.
  Constant *Init;
  if (DECL_INITIAL(decl) == 0 || DECL_INITIAL(decl) == error_mark_node) {
    // Reconvert the type in case the forward def of the global and the real def
    // differ in type (e.g. declared as 'int A[]', and defined as 'int A[100]').
    Type *Ty = ConvertType(TREE_TYPE(decl));
    Init = getDefaultValue(Ty);
  } else {
    // Temporarily set an initializer for the global, so we don't infinitely
    // recurse.  If we don't do this, we can hit cases where we see "oh a global
    // with an initializer hasn't been initialized yet, call emit_global on it".
    // When constructing the initializer it might refer to itself.
    // This can happen for things like void *G = &G;
    GV->setInitializer(UndefValue::get(GV->getType()->getElementType()));
    Init = ConvertInitializer(DECL_INITIAL(decl));
  }

  // Set the initializer.
  if (GV->getType()->getElementType() == Init->getType()) {
    GV->setInitializer(Init);
  } else if (GV == Init && GV->getType()->getElementType()->isPointerTy()) {
    // Global initialized to its own address, cast the address.
    Init = TheFolder->CreateBitCast(Init, GV->getType()->getElementType());
    GV->setInitializer(Init);
  } else {
    // If we had a forward definition that has a type that disagrees with our
    // initializer, insert a cast now.  This sort of thing occurs when we have a
    // global union, and the LLVM type followed a union initializer that is
    // different from the union element used for the type.
    GV->removeFromParent();
    GlobalVariable *NGV =
        new GlobalVariable(*TheModule, Init->getType(), GV->isConstant(),
                           GlobalValue::ExternalLinkage, 0, GV->getName());
    NGV->setInitializer(Init);
    GV->replaceAllUsesWith(TheFolder->CreateBitCast(NGV, GV->getType()));
    changeLLVMConstant(GV, NGV);
    SET_DECL_LLVM(decl, NGV);
    delete GV; // Frees Init if equal to GV.
    GV = NGV;
  }

  // Set the linkage.
  GlobalValue::LinkageTypes Linkage;

  if (false) { // FIXME DECL_LLVM_PRIVATE(decl)) {
    Linkage = GlobalValue::PrivateLinkage;
  } else if (false) { //FIXME DECL_LLVM_LINKER_PRIVATE(decl)) {
    Linkage = GlobalValue::LinkerPrivateLinkage;
  } else if (!TREE_PUBLIC(decl)) {
    Linkage = GlobalValue::InternalLinkage;
  } else if (DECL_WEAK(decl)) {
    // The user may have explicitly asked for weak linkage - ignore flag_odr.
    Linkage = GlobalValue::WeakAnyLinkage;
  } else if (DECL_ONE_ONLY(decl)) {
    Linkage = GlobalValue::getWeakLinkage(flag_odr);
  } else if (DECL_COMMON(decl) && // DECL_COMMON is only meaningful if no init
             (!DECL_INITIAL(decl) || DECL_INITIAL(decl) == error_mark_node)) {
    // llvm-gcc also includes DECL_VIRTUAL_P here.
    Linkage = GlobalValue::CommonLinkage;
  } else if (DECL_COMDAT(decl)) {
    Linkage = GlobalValue::getLinkOnceLinkage(flag_odr);
  } else {
    Linkage = GV->getLinkage();
  }

  // Allow loads from constants to be folded even if the constant has weak
  // linkage.  Do this by giving the constant weak_odr linkage rather than
  // weak linkage.  It is not clear whether this optimization is valid (see
  // gcc bug 36685), but mainline gcc chooses to do it, and fold may already
  // have done it, so we might as well join in with gusto.
  if (GV->isConstant()) {
    if (Linkage == GlobalValue::WeakAnyLinkage)
      Linkage = GlobalValue::WeakODRLinkage;
    else if (Linkage == GlobalValue::LinkOnceAnyLinkage)
      Linkage = GlobalValue::LinkOnceODRLinkage;
  }
  GV->setLinkage(Linkage);

#ifdef TARGET_ADJUST_LLVM_LINKAGE
  TARGET_ADJUST_LLVM_LINKAGE(GV, decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

  // If this is a variable that never has its address taken then allow it to be
  // merged with other variables (C and C++ say that different variables should
  // have different addresses, which is why this is only correct if the address
  // is not taken).  However if -fmerge-all-constants was specified then allow
  // merging even if the address was taken.  Note that merging will only happen
  // if the global is constant or later proved to be constant by the optimizers.
  GV->setUnnamedAddr(flag_merge_constants >= 2 || !TREE_ADDRESSABLE(decl));

  handleVisibility(decl, GV);

  // Set the section for the global.
  if (isa<VAR_DECL>(decl)) {
    if (DECL_SECTION_NAME(decl)) {
      GV->setSection(TREE_STRING_POINTER(DECL_SECTION_NAME(decl)));
#ifdef LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION
    } else if (const char *Section =
                   LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) {
      GV->setSection(Section);
#endif
    }

    GV->setAlignment(DECL_ALIGN(decl) / 8);
    assert(GV->getAlignment() != 0 && "Global variable has unknown alignment!");
#ifdef TARGET_ADJUST_CSTRING_ALIGN
    if (DECL_INITIAL(decl) != error_mark_node && // uninitialized?
        DECL_INITIAL(decl) && isa<STRING_CST>(DECL_INITIAL(decl)))
      TARGET_ADJUST_CSTRING_ALIGN(GV);
#endif

    // If this is the alignment we would have given the variable anyway and it
    // was not user specified, then don't use an explicit alignment, making the
    // IR look more portable.
    if (!DECL_USER_ALIGN(decl) &&
        GV->getAlignment() ==
        getDataLayout().getABITypeAlignment(GV->getType()->getElementType()))
      GV->setAlignment(0);

    // Handle used decls
    if (DECL_PRESERVE_P(decl)) {
      if (false) //FIXME DECL_LLVM_LINKER_PRIVATE (decl))
        AttributeCompilerUsedGlobals.insert(GV);
      else
        AttributeUsedGlobals.insert(GV);
    }

    // Add annotate attributes for globals
    if (DECL_ATTRIBUTES(decl))
      AddAnnotateAttrsToGlobal(GV, decl);

#ifdef LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION
  } else if (isa<CONST_DECL>(decl)) {
    if (const char *Section = LLVM_IMPLICIT_TARGET_GLOBAL_VAR_SECTION(decl)) {
      GV->setSection(Section);

/* LLVM LOCAL - begin radar 6389998 */
#ifdef TARGET_ADJUST_CFSTRING_NAME
      TARGET_ADJUST_CFSTRING_NAME(GV, Section);
#endif
      /* LLVM LOCAL - end radar 6389998 */
    }
#endif
  }

  if (TheDebugInfo)
    TheDebugInfo->EmitGlobalVariable(GV, decl);

  // Sanity check that the LLVM global has the right size.
  assert(SizeOfGlobalMatchesDecl(GV, decl) && "Global has wrong size!");

  // Mark the global as written so gcc doesn't waste time outputting it.
#if (GCC_MINOR < 8)
  TREE_ASM_WRITTEN(decl) = 1;
#endif

  // Output any associated aliases.
  if (isa<VAR_DECL>(decl))
    if (struct varpool_node *vnode =
#if (GCC_MINOR < 6)
            varpool_node(decl)
#else
        varpool_get_node(decl)
#endif
        )
      emit_varpool_aliases(vnode);

  //TODO  timevar_pop(TV_LLVM_GLOBALS);
}

/// ValidateRegisterVariable - Check that a static "asm" variable is
/// well-formed.  If not, emit error messages and return true.  If so, return
/// false.
bool ValidateRegisterVariable(tree decl) {
  const char *RegName = extractRegisterName(decl);
  int RegNumber = decode_reg_name(RegName);

  if (errorcount || sorrycount)
    return true; // Do not process broken code.

  /* Detect errors in declaring global registers.  */
  if (RegNumber == -1)
    error("register name not specified for %<%s%>", RegName);
  else if (RegNumber < 0)
    error("invalid register name for %<%s%>", RegName);
  else if (TYPE_MODE(TREE_TYPE(decl)) == BLKmode)
    error("data type of %<%s%> isn%'t suitable for a register", RegName);
#if 0 // FIXME: enable this.
  else if (!HARD_REGNO_MODE_OK(RegNumber, TYPE_MODE(TREE_TYPE(decl))))
    error("register specified for %<%s%> isn%'t suitable for data type",
          RegName);
#endif
  else if (DECL_INITIAL(decl) != 0 && TREE_STATIC(decl))
    error("global register variable has initial value");
  else if (isa<AGGREGATE_TYPE>(TREE_TYPE(decl)))
    sorry("LLVM cannot handle register variable %<%s%>, report a bug", RegName);
  else {
    if (TREE_THIS_VOLATILE(decl))
      warning(0, "volatile register variables don%'t work as you might wish");

    return false; // Everything ok.
  }

  return true;
}

/// make_decl_llvm - Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL
/// should have static storage duration.  In other words, it should not be an
/// automatic variable, including PARM_DECLs.
///
/// There is, however, one exception: this function handles variables explicitly
/// placed in a particular register by the user.
///
/// This function corresponds to make_decl_rtl in varasm.c, and is implicitly
/// called by DECL_LLVM if a decl doesn't have an LLVM set.
Value *make_decl_llvm(tree decl) {
  // If we already made the LLVM, then return it.
  if (Value *V = get_decl_llvm(decl))
    return V;

#ifndef NDEBUG
  // Check that we are not being given an automatic variable or a type or label.
  // A weak alias has TREE_PUBLIC set but not the other bits.
  if (isa<PARM_DECL>(decl) || isa<RESULT_DECL>(decl) || isa<TYPE_DECL>(decl) ||
      isa<LABEL_DECL>(decl) ||
      (isa<VAR_DECL>(decl) && !TREE_STATIC(decl) && !TREE_PUBLIC(decl) &&
       !DECL_EXTERNAL(decl) && !DECL_REGISTER(decl))) {
    debug_tree(decl);
    llvm_unreachable("Cannot make a global for this kind of declaration!");
  }
#endif

  if (errorcount || sorrycount)
    return NULL; // Do not process broken code.

  LLVMContext &Context = getGlobalContext();

  // Global register variable with asm name, e.g.:
  // register unsigned long esp __asm__("ebp");
  if (!isa<FUNCTION_DECL>(decl) && !isa<CONST_DECL>(decl) &&
      DECL_REGISTER(decl)) {
    // This just verifies that the variable is ok.  The actual "load/store"
    // code paths handle accesses to the variable.
    ValidateRegisterVariable(decl);
    return NULL;
  }

  //TODO  timevar_push(TV_LLVM_GLOBALS);

  std::string Name;
  if (!isa<CONST_DECL>(decl)) // CONST_DECLs do not have assembler names.
    Name = getAssemblerName(decl);

  // Now handle ordinary static variables and functions (in memory).
  // Also handle vars declared register invalidly.
  if (!Name.empty() && Name[0] == 1) {
#ifdef REGISTER_PREFIX
    if (strlen(REGISTER_PREFIX) != 0) {
      int reg_number = decode_reg_name(Name.c_str());
      if (reg_number >= 0 || reg_number == -3)
        error("register name given for non-register variable %q+D", decl);
    }
#endif
  }

  // Specifying a section attribute on a variable forces it into a
  // non-.bss section, and thus it cannot be common.
  if (isa<VAR_DECL>(decl) && DECL_SECTION_NAME(decl) != NULL_TREE &&
      DECL_INITIAL(decl) == NULL_TREE && DECL_COMMON(decl))
    DECL_COMMON(decl) = 0;

  // Variables can't be both common and weak.
  if (isa<VAR_DECL>(decl) && DECL_WEAK(decl))
    DECL_COMMON(decl) = 0;

  // Okay, now we need to create an LLVM global variable or function for this
  // object.  Note that this is quite possibly a forward reference to the
  // object, so its type may change later.
  if (isa<FUNCTION_DECL>(decl)) {
    assert(!Name.empty() && "Function with empty name!");
    // If this function has already been created, reuse the decl.  This happens
    // when we have something like __builtin_memset and memset in the same file.
    Function *FnEntry = TheModule->getFunction(Name);
    if (FnEntry == 0) {
      CallingConv::ID CC;
      AttributeSet PAL;
      FunctionType *Ty =
          ConvertFunctionType(TREE_TYPE(decl), decl, NULL, CC, PAL);
      FnEntry =
          Function::Create(Ty, Function::ExternalLinkage, Name, TheModule);
      FnEntry->setCallingConv(CC);
      FnEntry->setAttributes(PAL);

      // Check for external weak linkage.
      if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
        FnEntry->setLinkage(Function::ExternalWeakLinkage);

#ifdef TARGET_ADJUST_LLVM_LINKAGE
      TARGET_ADJUST_LLVM_LINKAGE(FnEntry, decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

      handleVisibility(decl, FnEntry);

      // If FnEntry got renamed, then there is already an object with this name
      // in the symbol table.  If this happens, the old one must be a forward
      // decl, just replace it with a cast of the new one.
      if (FnEntry->getName() != Name) {
        GlobalValue *G = TheModule->getNamedValue(Name);
        assert(G && (G->isDeclaration() || G->isWeakForLinker()) &&
               "A global turned into a function?");

        // Replace any uses of "G" with uses of FnEntry.
        Constant *GInNewType = TheFolder->CreateBitCast(FnEntry, G->getType());
        G->replaceAllUsesWith(GInNewType);

        // Update the decl that points to G.
        changeLLVMConstant(G, GInNewType);

        // Now we can give GV the proper name.
        FnEntry->takeName(G);

        // G is now dead, nuke it.
        G->eraseFromParent();
      }
    }
    return SET_DECL_LLVM(decl, FnEntry);
  } else {
    assert((isa<VAR_DECL>(decl) || isa<CONST_DECL>(decl)) &&
           "Not a function or var decl?");
    Type *Ty = ConvertType(TREE_TYPE(decl));
    GlobalVariable *GV;

    // If we have "extern void foo", make the global have type {} instead of
    // type void.
    if (Ty->isVoidTy())
      Ty = StructType::get(Context);

    if (Name.empty()) { // Global has no name.
      GV = new GlobalVariable(*TheModule, Ty, false,
                              GlobalValue::ExternalLinkage, 0, "");

      // Check for external weak linkage.
      if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
        GV->setLinkage(GlobalValue::ExternalWeakLinkage);

#ifdef TARGET_ADJUST_LLVM_LINKAGE
      TARGET_ADJUST_LLVM_LINKAGE(GV, decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

      handleVisibility(decl, GV);
    } else {
      // If the global has a name, prevent multiple vars with the same name from
      // being created.
      GlobalVariable *GVE = TheModule->getGlobalVariable(Name, true);

      if (GVE == 0) {
        GV = new GlobalVariable(*TheModule, Ty, false,
                                GlobalValue::ExternalLinkage, 0, Name);

        // Check for external weak linkage.
        if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
          GV->setLinkage(GlobalValue::ExternalWeakLinkage);

#ifdef TARGET_ADJUST_LLVM_LINKAGE
        TARGET_ADJUST_LLVM_LINKAGE(GV, decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

        handleVisibility(decl, GV);

        // If GV got renamed, then there is already an object with this name in
        // the symbol table.  If this happens, the old one must be a forward
        // decl, just replace it with a cast of the new one.
        if (GV->getName() != Name) {
          Function *F = TheModule->getFunction(Name);
          assert(F && F->isDeclaration() && "A function turned into a global?");

          // Replace any uses of "F" with uses of GV.
          Constant *FInNewType = TheFolder->CreateBitCast(GV, F->getType());
          F->replaceAllUsesWith(FInNewType);

          // Update the decl that points to F.
          changeLLVMConstant(F, FInNewType);

          // Now we can give GV the proper name.
          GV->takeName(F);

          // F is now dead, nuke it.
          F->eraseFromParent();
        }

      } else {
        GV = GVE; // Global already created, reuse it.
      }
    }

    if ((TREE_READONLY(decl) && !TREE_SIDE_EFFECTS(decl)) ||
        isa<CONST_DECL>(decl)) {
      if (DECL_EXTERNAL(decl)) {
        // Mark external globals constant even though they could be marked
        // non-constant in the defining translation unit.  The definition of the
        // global determines whether the global is ultimately constant or not,
        // marking this constant will allow us to do some extra (legal)
        // optimizations that we would otherwise not be able to do.  (In C++,
        // any global that is 'C++ const' may not be readonly: it could have a
        // dynamic initializer.
        //
        GV->setConstant(true);
      } else {
        // Mark readonly globals with constant initializers constant.
        if (DECL_INITIAL(decl) != error_mark_node && // uninitialized?
            DECL_INITIAL(decl) && (TREE_CONSTANT(DECL_INITIAL(decl)) ||
                                   isa<STRING_CST>(DECL_INITIAL(decl))))
          GV->setConstant(true);
      }
    }

    // Set thread local (TLS)
    if (isa<VAR_DECL>(decl) && DECL_THREAD_LOCAL_P(decl)) {
      GV->setThreadLocal(true);

      switch (DECL_TLS_MODEL(decl)) {
      case TLS_MODEL_NONE:
        llvm_unreachable("TLS_MODEL_NONE for thread local var is impossible");
      case TLS_MODEL_EMULATED:
        llvm_unreachable("LLVM does not support TLS_MODEL_EMULATED");
      case TLS_MODEL_GLOBAL_DYNAMIC:
        GV->setThreadLocalMode(GlobalVariable::GeneralDynamicTLSModel);
        break;
      case TLS_MODEL_LOCAL_DYNAMIC:
        GV->setThreadLocalMode(GlobalVariable::LocalDynamicTLSModel);
        break;
      case TLS_MODEL_INITIAL_EXEC:
        GV->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
        break;
      case TLS_MODEL_LOCAL_EXEC:
        GV->setThreadLocalMode(GlobalVariable::LocalExecTLSModel);
        break;
      }
    }

    assert((GV->isDeclaration() || SizeOfGlobalMatchesDecl(GV, decl)) &&
           "Global has unexpected initializer!");

    return SET_DECL_LLVM(decl, GV);
  }
  //TODO  timevar_pop(TV_LLVM_GLOBALS);
}

/// make_definition_llvm - Ensures that the body or initial value of the given
/// GCC global will be output, and returns a declaration for it.
Value *make_definition_llvm(tree decl) {
  // Only need to do something special for global variables.
  if (!isa<CONST_DECL>(decl) && !isa<VAR_DECL>(decl))
    return DECL_LLVM(decl);
  // Do not allocate storage for external references (eg: a "weakref" alias).
  if (DECL_EXTERNAL(decl))
    return DECL_LLVM(decl);
  // Can only assign initial values to global variables in static storage.
  if (!TREE_STATIC(decl)) {
    assert(!DECL_INITIAL(decl) && "Non-static global has initial value!");
    return DECL_LLVM(decl);
  }
  GlobalValue *GV = cast<GlobalValue>(DECL_LLVM(decl));
  // If we already output a definition for this declaration, then reuse it.
  if (!GV->isDeclaration())
    return GV;
  emit_global(decl);
  return DECL_LLVM(decl); // Decl could have changed if it changed type.
}

/// register_ctor_dtor - Called to register static ctors/dtors with LLVM.
/// Fn is a 'void()' ctor/dtor function to be run, initprio is the init
/// priority, and isCtor indicates whether this is a ctor or dtor.
void register_ctor_dtor(Function *Fn, int InitPrio, bool isCtor) {
  (isCtor ? &StaticCtors : &StaticDtors)
      ->push_back(std::make_pair(Fn, InitPrio));
}

/// extractRegisterName - Get a register name given its decl. In 4.2 unlike 4.0
/// these names have been run through set_user_assembler_name which means they
/// may have a leading star at this point; compensate.
const char *extractRegisterName(tree decl) {
  const char *Name = IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(decl));
  return (*Name == '*') ? Name + 1 : Name;
}

/// FinalizePlugin - Shutdown the plugin.
static void FinalizePlugin(void) {
  static bool Finalized = false;
  if (Finalized)
    return;

#ifndef NDEBUG
  delete PerModulePasses;
  delete PerFunctionPasses;
  delete CodeGenPasses;
  delete TheModule;
  llvm_shutdown();
#endif

  Finalized = true;
}

/// TakeoverAsmOutput - Obtain exclusive use of the assembly code output file.
/// Any GCC output will be thrown away.
static void TakeoverAsmOutput(void) {
  // Calculate the output file name as in init_asm_output (toplev.c).
  if (!dump_base_name && main_input_filename)
    dump_base_name = main_input_filename[0] ? main_input_filename : "gccdump";

  if (!main_input_filename && !asm_file_name) {
    llvm_asm_file_name = "-";
  } else if (!asm_file_name) {
    int len = strlen(dump_base_name);
    char *dumpname = XNEWVEC(char, len + 6);

    memcpy(dumpname, dump_base_name, len + 1);
    strip_off_ending(dumpname, len);
    strcat(dumpname, ".s");
    llvm_asm_file_name = dumpname;
  } else {
    llvm_asm_file_name = asm_file_name;
  }

  if (!SaveGCCOutput) {
    // Redirect any GCC output to /dev/null.
    asm_file_name = HOST_BIT_BUCKET;
  } else {
    // Save GCC output to a special file.  Good for seeing how much pointless
    // output gcc is producing.
    int len = strlen(llvm_asm_file_name);
    char *name = XNEWVEC(char, len + 5);
    memcpy(name, llvm_asm_file_name, len + 1);
    asm_file_name = strcat(name, ".gcc");
  }
}

/// no_target_thunks - Hook for can_output_mi_thunk that always says "no".
static bool no_target_thunks(const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
                             const_tree) {
  return false;
}

//===----------------------------------------------------------------------===//
//                             Plugin interface
//===----------------------------------------------------------------------===//

// This plugin's code is licensed under the GPLv2 or later.  The LLVM libraries
// use the GPL compatible University of Illinois/NCSA Open Source License.  The
// plugin is GPL compatible.
int plugin_is_GPL_compatible __attribute__((visibility("default")));

/// llvm_start_unit - Perform late initialization.  This is called by GCC just
/// before processing the compilation unit.
/// NOTE: called even when only doing syntax checking, so do not initialize the
/// module etc here.
static void llvm_start_unit(void */*gcc_data*/, void */*user_data*/) {
  if (!quiet_flag)
    errs() << "Starting compilation unit\n";

#ifdef ENABLE_LTO
  // Output LLVM IR if the user requested generation of lto data.
  EmitIR |= flag_generate_lto != 0;
  // We have the same needs as GCC's LTO.  Always claim to be doing LTO.
  flag_lto =
#if (GCC_MINOR > 5)
      "";
#else
  1;
#endif
  flag_generate_lto = 1;
  flag_whole_program = 0;
#endif

  // Stop GCC outputting serious amounts of debug info.
  debug_hooks = &do_nothing_debug_hooks;

  // Adjust the target machine configuration for the fact that we are really
  // targetting LLVM IR.

  // Ensure that thunks are turned into functions rather than output directly
  // as assembler.
  targetm.asm_out.can_output_mi_thunk = no_target_thunks;

  // Ensure that GCC doesn't decorate stdcall and fastcall function names:
  // LLVM codegen takes care of this, and we don't want them decorated twice.
  targetm.mangle_decl_assembler_name = default_mangle_decl_assembler_name;

#if (GCC_MINOR > 7)
  // Arrange for a special .ident directive identifying the compiler and plugin
  // versions to be inserted into the final assembler.
  targetm.asm_out.output_ident = output_ident;
#endif
}

/// emit_cgraph_aliases - Output any aliases associated with the given cgraph
/// node.
static void emit_cgraph_aliases(struct cgraph_node *node) {
#if (GCC_MINOR < 7)
  struct cgraph_node *alias, *next;
  for (alias = node->same_body; alias && alias->next; alias = alias->next)
    ;
  for (; alias; alias = next) {
    next = alias->previous;
    if (!alias->thunk.thunk_p)
      emit_alias(alias->decl, alias->thunk.alias);
  }
#else
  // There is no need to walk thunks here (cf. cgraphunit), because we arrange
  // for thunks to be output as functions and thus visit thunk aliases when the
  // thunk function is output.
  struct ipa_ref *ref;
  for (int i = 0;
       ipa_ref_list_referring_iterate(&cgraph_symbol(node)->ref_list, i, ref);
       i++)
    if (ref->use == IPA_REF_ALIAS) {
      struct cgraph_node *alias = ipa_ref_referring_node(ref);
      emit_alias(cgraph_symbol(alias)->decl, alias->thunk.alias);
      emit_cgraph_aliases(alias);
    }
#endif
}

/// emit_current_function - Turn the current gimple function into LLVM IR.  This
/// is called once for each function in the compilation unit.
static void emit_current_function() {
  if (!quiet_flag && DECL_NAME(current_function_decl))
    errs() << getDescriptiveName(current_function_decl);

  // Convert the AST to raw/ugly LLVM code.
  Function *Fn;
  {
    TreeToLLVM Emitter(current_function_decl);
    Fn = Emitter.EmitFunction();
  }

  // Output any associated aliases.
  emit_cgraph_aliases(cgraph_get_node(current_function_decl));

  if (!errorcount && !sorrycount) { // Do not process broken code.
    createPerFunctionOptimizationPasses();

    if (PerFunctionPasses)
      PerFunctionPasses->run(*Fn);

    // TODO: Nuke the .ll code for the function at -O[01] if we don't want to
    // inline it or something else.
  }
}

/// rtl_emit_function - Turn a gimple function into LLVM IR.  This is called
/// once for each function in the compilation unit if GCC optimizations are
/// enabled.
static unsigned int rtl_emit_function(void) {
  if (!errorcount && !sorrycount) {
    InitializeBackend();
    // Convert the function.
    emit_current_function();
  }

  // Free tree-ssa data structures.
#if (GCC_MINOR < 8)
  execute_free_datastructures();
#else
  free_dominance_info(CDI_DOMINATORS);
  free_dominance_info(CDI_POST_DOMINATORS);
  // And get rid of annotations we no longer need.
  delete_tree_cfg_annotations();
#endif

  // Finally, we have written out this function!
  TREE_ASM_WRITTEN(current_function_decl) = 1;
  return 0;
}

/// pass_rtl_emit_function - RTL pass that converts a function to LLVM IR.
static struct rtl_opt_pass pass_rtl_emit_function = { {
  RTL_PASS, "rtl_emit_function",         /* name */
#if (GCC_MINOR >= 8)
  OPTGROUP_NONE,                         /* optinfo_flags */
#endif
  NULL,                                  /* gate */
  rtl_emit_function,                     /* execute */
  NULL,                                  /* sub */
  NULL,                                  /* next */
  0,                                     /* static_pass_number */
  TV_NONE,                               /* tv_id */
  PROP_ssa | PROP_gimple_leh | PROP_cfg, /* properties_required */
  0,                                     /* properties_provided */
  PROP_ssa | PROP_trees,                 /* properties_destroyed */
  TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts, /* todo_flags_start */
  TODO_ggc_collect /* todo_flags_finish */
} };

/// emit_file_scope_asms - Output any file-scope assembly.
static void emit_file_scope_asms() {
  for (struct asm_node *anode = asm_nodes; anode; anode = anode->next) {
    tree string = anode->asm_str;
    if (isa<ADDR_EXPR>(string))
      string = TREE_OPERAND(string, 0);
    TheModule->appendModuleInlineAsm(TREE_STRING_POINTER(string));
  }
  // Remove the asms so gcc doesn't waste time outputting them.
  asm_nodes = NULL;
}

#if (GCC_MINOR > 6)
/// get_alias_symbol - Return the name of the aliasee for this alias.
static tree get_alias_symbol(tree decl) {
  tree alias = lookup_attribute("alias", DECL_ATTRIBUTES(decl));
  return get_identifier(TREE_STRING_POINTER(TREE_VALUE(TREE_VALUE(alias))));
}

/// emit_cgraph_weakrefs - Output any cgraph weak references to external
/// declarations.
static void emit_cgraph_weakrefs() {
  struct cgraph_node *node;
  FOR_EACH_FUNCTION(node)
    if (node->alias && DECL_EXTERNAL(cgraph_symbol(node)->decl) &&
        lookup_attribute("weakref", DECL_ATTRIBUTES(cgraph_symbol(node)->decl)))
      emit_alias(cgraph_symbol(node)->decl, node->thunk.alias ?
                 node->thunk.alias :
                 get_alias_symbol(cgraph_symbol(node)->decl));
}

/// emit_varpool_weakrefs - Output any varpool weak references to external
/// declarations.
static void emit_varpool_weakrefs() {
  struct varpool_node *vnode;
  FOR_EACH_VARIABLE(vnode)
    if (vnode->alias && DECL_EXTERNAL(varpool_symbol(vnode)->decl) &&
        lookup_attribute("weakref",
                         DECL_ATTRIBUTES(varpool_symbol(vnode)->decl)))
      emit_alias(varpool_symbol(vnode)->decl, vnode->alias_of ? vnode->alias_of
                 : get_alias_symbol(varpool_symbol(vnode)->decl));
}
#endif

#if (GCC_MINOR < 8)
INSTANTIATE_VECTOR(alias_pair);
#endif

/// llvm_emit_globals - Output GCC global variables, aliases and asm's to the
/// LLVM IR.
static void llvm_emit_globals(void * /*gcc_data*/, void * /*user_data*/) {
  if (errorcount || sorrycount)
    return; // Do not process broken code.

  InitializeBackend();

  // Emit any file-scope asms.
  emit_file_scope_asms();

  // Some global variables must be output even if unused, for example because
  // they are externally visible.  Output them now.  All other variables are
  // output when their user is, or discarded if unused.
  struct varpool_node *vnode;
  FOR_EACH_VARIABLE(vnode) {
    // If the node is explicitly marked as not being needed, then skip it.
#if (GCC_MINOR < 8)
    if (!vnode->needed)
      continue;
#endif
    // If the node is an alias then skip it - aliases are handled below.
    if (vnode->alias)
      continue;

    // If this variable must be output even if unused then output it.
    tree decl = varpool_symbol(vnode)->decl;
    if (vnode->analyzed &&
        (
#if (GCC_MINOR > 5)
            !varpool_can_remove_if_no_refs(vnode)
#else
            vnode->force_output ||
            (!DECL_COMDAT(decl) &&
             (!DECL_ARTIFICIAL(decl) || vnode->externally_visible))
#endif
            ))
      // TODO: Remove the check on the following lines.  It only exists to avoid
      // outputting block addresses when not compiling the function containing
      // the block.  We need to support outputting block addresses at odd times
      // anyway since the GCC optimizers can generate these.
      if (isa<VAR_DECL>(decl) && !DECL_EXTERNAL(decl) &&
          (TREE_PUBLIC(decl) || DECL_PRESERVE_P(decl) ||
           TREE_THIS_VOLATILE(decl)))
        emit_global(decl);
  }

#if (GCC_MINOR > 6)
  // Aliases of functions and global variables with bodies are output when the
  // body is.  Output any aliases (weak references) of globals without bodies,
  // i.e. external declarations, now.
  emit_cgraph_weakrefs();
  emit_varpool_weakrefs();
#endif

  // Emit any aliases that aren't represented in cgraph or varpool, for example
  // a function that aliases a variable or a variable that aliases a function.
  if (alias_pairs) {
    alias_pair *p;
    const vec<alias_pair, va_gc> &pairs = *alias_pairs;
    for (unsigned i = 0; pairs.iterate(i, &p); i++)
      emit_alias(p->decl, p->target);
  }
}

static void InlineAsmDiagnosticHandler(const SMDiagnostic &D, void */*Data*/,
                                       location_t loc) {
  std::string S = D.getMessage().str(); // Ensure Message is not dangling.
  const char *Message = S.c_str();
  switch (D.getKind()) {
  case SourceMgr::DK_Error:
    error_at(loc, "%s", Message);
    break;
  case SourceMgr::DK_Warning:
    warning_at(loc, 0, "%s", Message);
    break;
  case SourceMgr::DK_Note:
    inform(loc, "%s", Message);
    break;
  }
}

/// llvm_finish_unit - Finish the .s file.  This is called by GCC once the
/// compilation unit has been completely processed.
static void llvm_finish_unit(void */*gcc_data*/, void */*user_data*/) {
  if (errorcount || sorrycount)
    return; // Do not process broken code.

  //TODO  timevar_push(TV_LLVM_PERFILE);
  if (!quiet_flag)
    errs() << "Finishing compilation unit\n";

  InitializeBackend();
  if (TheDebugInfo) {
    delete TheDebugInfo;
    TheDebugInfo = 0;
  }

  LLVMContext &Context = getGlobalContext();

  createPerFunctionOptimizationPasses();

  //TODO  for (Module::iterator I = TheModule->begin(), E = TheModule->end();
  //TODO       I != E; ++I)
  //TODO    if (!I->isDeclaration()) {
  //TODO      if (flag_disable_red_zone)
  //TODO        I->addFnAttr(Attribute::NoRedZone);
  //TODO      if (flag_no_implicit_float)
  //TODO        I->addFnAttr(Attribute::NoImplicitFloat);
  //TODO    }

  // Add an llvm.global_ctors global if needed.
  if (!StaticCtors.empty())
    CreateStructorsList(StaticCtors, "llvm.global_ctors");
  // Add an llvm.global_dtors global if needed.
  if (!StaticDtors.empty())
    CreateStructorsList(StaticDtors, "llvm.global_dtors");

  if (!AttributeUsedGlobals.empty()) {
    std::vector<Constant *> AUGs;
    Type *SBP = Type::getInt8PtrTy(Context);
    for (SmallSetVector<Constant *, 32>::iterator
             AI = AttributeUsedGlobals.begin(),
             AE = AttributeUsedGlobals.end();
         AI != AE; ++AI) {
      Constant *C = *AI;
      AUGs.push_back(TheFolder->CreateBitCast(C, SBP));
    }

    ArrayType *AT = ArrayType::get(SBP, AUGs.size());
    Constant *Init = ConstantArray::get(AT, AUGs);
    GlobalValue *gv =
        new GlobalVariable(*TheModule, AT, false, GlobalValue::AppendingLinkage,
                           Init, "llvm.used");
    gv->setSection("llvm.metadata");
    AttributeUsedGlobals.clear();
  }

  if (!AttributeCompilerUsedGlobals.empty()) {
    std::vector<Constant *> ACUGs;
    Type *SBP = Type::getInt8PtrTy(Context);
    for (SmallSetVector<Constant *, 32>::iterator
             AI = AttributeCompilerUsedGlobals.begin(),
             AE = AttributeCompilerUsedGlobals.end();
         AI != AE; ++AI) {
      Constant *C = *AI;
      ACUGs.push_back(TheFolder->CreateBitCast(C, SBP));
    }

    ArrayType *AT = ArrayType::get(SBP, ACUGs.size());
    Constant *Init = ConstantArray::get(AT, ACUGs);
    GlobalValue *gv =
        new GlobalVariable(*TheModule, AT, false, GlobalValue::AppendingLinkage,
                           Init, "llvm.compiler.used");
    gv->setSection("llvm.metadata");
    AttributeCompilerUsedGlobals.clear();
  }

  // Add llvm.global.annotations
  if (!AttributeAnnotateGlobals.empty()) {
    Constant *Array = ConstantArray::get(
        ArrayType::get(AttributeAnnotateGlobals[0]->getType(),
                       AttributeAnnotateGlobals.size()),
        AttributeAnnotateGlobals);
    GlobalValue *gv = new GlobalVariable(*TheModule, Array->getType(), false,
                                         GlobalValue::AppendingLinkage, Array,
                                         "llvm.global.annotations");
    gv->setSection("llvm.metadata");
    AttributeAnnotateGlobals.clear();
  }

  // Finish off the per-function pass.
  if (PerFunctionPasses)
    PerFunctionPasses->doFinalization();

  // Run module-level optimizers, if any are present.
  createPerModuleOptimizationPasses();
  if (PerModulePasses)
    PerModulePasses->run(*TheModule);

  // Run the code generator, if present.
  if (CodeGenPasses) {
    // Arrange for inline asm problems to be printed nicely.
    LLVMContext::InlineAsmDiagHandlerTy OldHandler =
        Context.getInlineAsmDiagnosticHandler();
    void *OldHandlerData = Context.getInlineAsmDiagnosticContext();
    Context.setInlineAsmDiagnosticHandler(InlineAsmDiagnosticHandler, 0);

    CodeGenPasses->doInitialization();
    for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;
         ++I)
      if (!I->isDeclaration())
        CodeGenPasses->run(*I);
    CodeGenPasses->doFinalization();

    Context.setInlineAsmDiagnosticHandler(OldHandler, OldHandlerData);
  }

  FormattedOutStream.flush();
  OutStream->flush();
  //TODO  timevar_pop(TV_LLVM_PERFILE);

  // We have finished - shutdown the plugin.  Doing this here ensures that timer
  // info and other statistics are not intermingled with those produced by GCC.
  FinalizePlugin();
}

/// llvm_finish - Run shutdown code when GCC exits.
static void llvm_finish(void */*gcc_data*/, void */*user_data*/) {
  FinalizePlugin();
}

/// gate_null - Gate method for a pass that does nothing.
static bool gate_null(void) { return false; }

/// pass_gimple_null - Gimple pass that does nothing.
static struct gimple_opt_pass pass_gimple_null = { {
  GIMPLE_PASS, "*gimple_null", /* name */
#if (GCC_MINOR >= 8)
  OPTGROUP_NONE,               /* optinfo_flags */
#endif
  gate_null,                   /* gate */
  NULL,                        /* execute */
  NULL,                        /* sub */
  NULL,                        /* next */
  0,                           /* static_pass_number */
  TV_NONE,                     /* tv_id */
  0,                           /* properties_required */
  0,                           /* properties_provided */
  0,                           /* properties_destroyed */
  0,                           /* todo_flags_start */
  0                            /* todo_flags_finish */
} };

/// execute_correct_state - Correct the cgraph state to ensure that newly
/// inserted functions are processed before being converted to LLVM IR.
static unsigned int execute_correct_state(void) {
  if (cgraph_state < CGRAPH_STATE_IPA_SSA)
    cgraph_state = CGRAPH_STATE_IPA_SSA;
  return 0;
}

/// gate_correct_state - Gate method for pass_gimple_correct_state.
static bool gate_correct_state(void) { return true; }

/// pass_gimple_correct_state - Gimple pass that corrects the cgraph state so
/// newly inserted functions are processed before being converted to LLVM IR.
static struct gimple_opt_pass pass_gimple_correct_state = { {
  GIMPLE_PASS, "*gimple_correct_state", /* name */
#if (GCC_MINOR >= 8)
  OPTGROUP_NONE,                        /* optinfo_flags */
#endif
  gate_correct_state,                   /* gate */
  execute_correct_state,                /* execute */
  NULL,                                 /* sub */
  NULL,                                 /* next */
  0,                                    /* static_pass_number */
  TV_NONE,                              /* tv_id */
  0,                                    /* properties_required */
  0,                                    /* properties_provided */
  0,                                    /* properties_destroyed */
  0,                                    /* todo_flags_start */
  0                                     /* todo_flags_finish */
} };

/// pass_ipa_null - IPA pass that does nothing.
static struct ipa_opt_pass_d pass_ipa_null = {
  { IPA_PASS, "*ipa_null", /* name */
#if (GCC_MINOR >= 8)
    OPTGROUP_NONE,         /* optinfo_flags */
#endif
    gate_null,             /* gate */
    NULL,                  /* execute */
    NULL,                  /* sub */
    NULL,                  /* next */
    0,                     /* static_pass_number */
    TV_NONE,               /* tv_id */
    0,                     /* properties_required */
    0,                     /* properties_provided */
    0,                     /* properties_destroyed */
    0,                     /* todo_flags_start */
    0                      /* todo_flags_finish */
},
  NULL,                    /* generate_summary */
  NULL,                    /* write_summary */
  NULL,                    /* read_summary */
#if (GCC_MINOR > 5)
  NULL,                    /* write_optimization_summary */
  NULL,                    /* read_optimization_summary */
#else
  NULL,                    /* function_read_summary */
#endif
  NULL,                    /* stmt_fixup */
  0,                       /* function_transform_todo_flags_start */
  NULL,                    /* function_transform */
  NULL                     /* variable_transform */
};

/// pass_rtl_null - RTL pass that does nothing.
static struct rtl_opt_pass pass_rtl_null = { { RTL_PASS, "*rtl_null", /* name */
#if (GCC_MINOR >= 8)
                                               OPTGROUP_NONE,/* optinfo_flags */
#endif
                                               gate_null,             /* gate */
                                               NULL,    /* execute */
                                               NULL,    /* sub */
                                               NULL,    /* next */
                                               0,       /* static_pass_number */
                                               TV_NONE, /* tv_id */
                                               0, /* properties_required */
                                               0, /* properties_provided */
                                               0, /* properties_destroyed */
                                               0, /* todo_flags_start */
                                               0  /* todo_flags_finish */
} };

/// pass_simple_ipa_null - Simple IPA pass that does nothing.
static struct simple_ipa_opt_pass pass_simple_ipa_null = { {
  SIMPLE_IPA_PASS, "*simple_ipa_null", /* name */
#if (GCC_MINOR >= 8)
  OPTGROUP_NONE,                       /* optinfo_flags */
#endif
  gate_null,                           /* gate */
  NULL,                                /* execute */
  NULL,                                /* sub */
  NULL,                                /* next */
  0,                                   /* static_pass_number */
  TV_NONE,                             /* tv_id */
  0,                                   /* properties_required */
  0,                                   /* properties_provided */
  0,                                   /* properties_destroyed */
  0,                                   /* todo_flags_start */
  0                                    /* todo_flags_finish */
} };

// Garbage collector roots.
extern const struct ggc_cache_tab gt_ggc_rc__gt_cache_h[];

/// PluginFlags - Flag arguments for the plugin.

struct FlagDescriptor {
  const char *Key; // The plugin argument is -fplugin-arg-llvm-KEY.
  bool *Flag;      // Set to true if the flag is seen.
};

static FlagDescriptor PluginFlags[] = {
  { "debug-pass-structure", &DebugPassStructure },
  { "debug-pass-arguments", &DebugPassArguments },
  { "enable-gcc-optzns", &EnableGCCOptimizations }, { "emit-ir", &EmitIR },
  { "emit-obj", &EmitObj },
  { "save-gcc-output", &SaveGCCOutput }, { NULL, NULL } // Terminator.
};

/// llvm_plugin_info - Information about this plugin.  Users can access this
/// using "gcc --help -v".
static struct plugin_info llvm_plugin_info = {
  LLVM_VERSION, // version
                // TODO provide something useful here
  NULL          // help
};

#ifndef DISABLE_VERSION_CHECK
static bool version_check(struct plugin_gcc_version *plugged_in_version) {
  // Check that the running gcc has exactly the same version as the gcc we were
  // built against.  This strict check seems wise when developing against a fast
  // moving gcc tree.  TODO: Use a milder check if doing a "release build".
  return plugin_default_version_check(&gcc_version, plugged_in_version);
}
#endif

/// plugin_init - Plugin initialization routine, called by GCC.  This is the
/// first code executed in the plugin (except for constructors).  Configure
/// the plugin and setup GCC, taking over optimization and code generation.
int __attribute__((visibility("default"))) plugin_init(
    struct plugin_name_args *plugin_info, struct plugin_gcc_version *
#ifndef DISABLE_VERSION_CHECK
        version
#endif
    ) {
  const char *plugin_name = plugin_info->base_name;
  struct register_pass_info pass_info;

#ifndef DISABLE_VERSION_CHECK
  // Check that the plugin is compatible with the running gcc.
  if (!version_check(version)) {
    errs() << "Incompatible plugin version\n";
    return 1;
  }
#endif

  // Provide GCC with our version and help information.
  register_callback(plugin_name, PLUGIN_INFO, NULL, &llvm_plugin_info);

  // Process any plugin arguments.
  {
    struct plugin_argument *argv = plugin_info->argv;
    int argc = plugin_info->argc;

    for (int i = 0; i < argc; ++i) {
      if (!strcmp(argv[i].key, "llvm-ir-optimize") ||
          !strcmp(argv[i].key, "llvm-codegen-optimize")) {
        if (!argv[i].value) {
          error(G_("no value supplied for option '-fplugin-arg-%s-%s'"),
                plugin_name, argv[i].key);
          continue;
        }
        if (argv[i].value[0] < '0' || argv[i].value[0] > '9' ||
            argv[i].value[1]) {
          error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"),
                plugin_name, argv[i].key, argv[i].value);
          continue;
        }
        int OptLevel = argv[i].value[0] - '0';
        if (argv[i].key[5] == 'i')
          LLVMIROptimizeArg = OptLevel;
        else
          LLVMCodeGenOptimizeArg = OptLevel;
        continue;
      }

      if (!strcmp(argv[i].key, "llvm-option")) {
        if (!argv[i].value) {
          error(G_("no value supplied for option '-fplugin-arg-%s-%s'"),
                plugin_name, argv[i].key);
          continue;
        }
        std::string value(argv[i].value);
        // Split the value at spaces, making it possible to pass several options
        // in one 'llvm-option' value.  Turn ':' into '=' everywhere because '='
        // is useful for passing settings to LLVM but GCC doesn't allow it.
        std::string::iterator first = value.begin(); // Start of next sub-option
        for (std::string::iterator I = value.begin(), E = value.end(); I != E;
             ++I) {
          char C = *I;
          if (C == ':') {
            // Turn colons into equals signs, otherwise there is no way to use
            // an option that needs an equals sign.
            *I = '=';
          } else if (C == ' ') {
            // A space - split the string.
            std::string option(first, I);
            // Don't bother with empty options (multiple spaces cause these).
            if (option != "")
              ArgStrings.push_back(option);
            first = I;
            ++first;
          }
        }
        // Add the last option. If there were no spaces then this is everything.
        std::string option(first, value.end());
        if (option != "")
          ArgStrings.push_back(option);
        continue;
      }

      // All remaining options are flags, so complain if there is an argument.
      if (argv[i].value) {
        error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"),
              plugin_name, argv[i].key, argv[i].value);
        continue;
      }

      // Look for a matching flag.
      bool Found = false;
      for (FlagDescriptor *F = PluginFlags; F->Key; ++F)
        if (!strcmp(argv[i].key, F->Key)) {
          Found = true;
          *F->Flag = true;
          break;
        }

      if (!Found)
        warning(0, G_("unrecognised option '-fplugin-arg-%s-%s'"), plugin_name,
                argv[i].key);
    }
  }

  // Obtain exclusive use of the assembly code output file.  This stops GCC from
  // writing anything at all to the assembly file - only we get to write to it.
  TakeoverAsmOutput();

  // Register our garbage collector roots.
  register_callback(plugin_name, PLUGIN_REGISTER_GGC_CACHES, NULL,
                    const_cast<ggc_cache_tab *>(gt_ggc_rc__gt_cache_h));

  // Perform late initialization just before processing the compilation unit.
  register_callback(plugin_name, PLUGIN_START_UNIT, llvm_start_unit, NULL);

  // Turn off all gcc optimization passes.
  if (!EnableGCCOptimizations) {
// TODO: figure out a good way of turning off ipa optimization passes.
// Could just set optimize to zero (after taking a copy), but this would
// also impact front-end optimizations.

// Leave pass_ipa_free_lang_data.

// Leave pass_ipa_function_and_variable_visibility.  Needed for correctness.

#if (GCC_MINOR < 6)
    // Turn off pass_ipa_early_inline.
    pass_info.pass = &pass_simple_ipa_null.pass;
    pass_info.reference_pass_name = "einline_ipa";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
#endif

    // Leave pass pass_early_local_passes::pass_fixup_cfg. ???

    // Leave pass_early_local_passes::pass_init_datastructures. ???

    // Leave pass_early_local_passes::pass_expand_omp.

    // Leave pass_early_local_passes::pass_referenced_vars. ???

    // Leave pass_early_local_passes::pass_build_ssa.

    // Turn off pass_lower_vector.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "veclower";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Leave pass_early_local_passes::pass_early_warn_uninitialized.

    // Leave pass_early_local_passes::pass_rebuild_cgraph_edges. ???

    // Leave pass_inline_parameters.  Otherwise our vector lowering fails since
    // immediates have not been propagated into builtin callsites.

    // Leave pass_early_inline.  This handles extern inline functions.
    // TODO: Work out a way of making such functions visible in the LLVM IR.

    // Insert a pass that ensures that any newly inserted functions, for example
    // those generated by OMP expansion, are processed before being converted to
    // LLVM IR.
    pass_info.pass = &pass_gimple_correct_state.pass;
    pass_info.reference_pass_name = "early_optimizations";
    pass_info.ref_pass_instance_number = 1;
    pass_info.pos_op = PASS_POS_INSERT_BEFORE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Turn off pass_early_local_passes::pass_all_early_optimizations.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "early_optimizations";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Leave pass_early_local_passes::pass_release_ssa_names. ???

    // Leave pass_early_local_passes::pass_rebuild_cgraph_edges. ???

    // Leave pass_inline_parameters.  Otherwise our vector lowering fails since
    // immediates have not been propagated into builtin callsites.

    // Leave pass pass_early_local_passes::pass_tree_profile.

    // Turn off pass_ipa_increase_alignment.
    pass_info.pass = &pass_simple_ipa_null.pass;
    pass_info.reference_pass_name = "increase_alignment";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

#if (GCC_MINOR < 8)
    // Turn off pass_ipa_matrix_reorg.
    pass_info.pass = &pass_simple_ipa_null.pass;
    pass_info.reference_pass_name = "matrix-reorg";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
#endif

    // Leave pass_ipa_tm.

    // Leave pass_ipa_lower_emutls. ???

    // Leave pass_ipa_whole_program_visibility. ???

    // Leave pass_ipa_profile. ???

    // Turn off pass_ipa_cp.
    pass_info.pass = &pass_ipa_null.pass;
    pass_info.reference_pass_name = "cp";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Leave pass_ipa_cdtor_merge.

    // Turn off pass_ipa_inline.
    pass_info.pass = &pass_ipa_null.pass;
    pass_info.reference_pass_name = "inline";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Turn off pass_ipa_pure_const.
    pass_info.pass = &pass_ipa_null.pass;
    pass_info.reference_pass_name = "pure-const";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Turn off pass_ipa_reference.
    pass_info.pass = &pass_ipa_null.pass;
    pass_info.reference_pass_name = "static-var";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

#if (GCC_MINOR < 7)
    // Turn off pass_ipa_type_escape.
    pass_info.pass = &pass_simple_ipa_null.pass;
    pass_info.reference_pass_name = "type-escape-var";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
#endif

    // Turn off pass_ipa_pta.
    pass_info.pass = &pass_simple_ipa_null.pass;
    pass_info.reference_pass_name = "pta";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

#if (GCC_MINOR < 7)
    // Turn off pass_ipa_struct_reorg.
    pass_info.pass = &pass_simple_ipa_null.pass;
    pass_info.reference_pass_name = "ipa_struct_reorg";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
#endif
  }

  // Disable all LTO passes.
  pass_info.pass = &pass_ipa_null.pass;
  pass_info.reference_pass_name = "lto_gimple_out";
  pass_info.ref_pass_instance_number = 0;
  pass_info.pos_op = PASS_POS_REPLACE;
  register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

  pass_info.pass = &pass_ipa_null.pass;
  pass_info.reference_pass_name = "lto_decls_out";
  pass_info.ref_pass_instance_number = 0;
  pass_info.pos_op = PASS_POS_REPLACE;
  register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

#if (GCC_MINOR < 6)
  pass_info.pass = &pass_ipa_null.pass;
  pass_info.reference_pass_name = "lto_wpa_fixup";
  pass_info.ref_pass_instance_number = 0;
  pass_info.pos_op = PASS_POS_REPLACE;
  register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
#endif

  // Output GCC global variables, aliases and asm's to the IR.  This needs to be
  // done before the compilation unit is finished, since aliases are no longer
  // available then.  On the other hand it seems wise to output them after the
  // IPA passes have run, since these are the passes that modify globals.
  register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_END, llvm_emit_globals,
                    NULL);

  if (!EnableGCCOptimizations) {
    // Disable pass_lower_eh_dispatch.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "ehdisp";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Disable pass_all_optimizations.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "*all_optimizations";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Leave pass_tm_init.

    // Disable pass_lower_complex_O0.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "cplxlower0";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Disable pass_cleanup_eh.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "ehcleanup";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Disable pass_lower_resx.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "resx";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Disable pass_nrv.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "nrv";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Disable pass_mudflap_2. ???
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "mudflap2";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // Disable pass_cleanup_cfg_post_optimizing.
    pass_info.pass = &pass_gimple_null.pass;
    pass_info.reference_pass_name = "optimized";
    pass_info.ref_pass_instance_number = 0;
    pass_info.pos_op = PASS_POS_REPLACE;
    register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

    // TODO: Disable pass_warn_function_noreturn?
  }

  // Replace rtl expansion with a pass that converts functions to LLVM IR.
  pass_info.pass = &pass_rtl_emit_function.pass;
  pass_info.reference_pass_name = "expand";
  pass_info.ref_pass_instance_number = 0;
  pass_info.pos_op = PASS_POS_REPLACE;
  register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

  // Turn off all other rtl passes.
#if (GCC_MINOR < 8)
  pass_info.pass = &pass_gimple_null.pass;
#else
  pass_info.pass = &pass_rtl_null.pass;
#endif
  pass_info.reference_pass_name = "*rest_of_compilation";
  pass_info.ref_pass_instance_number = 0;
  pass_info.pos_op = PASS_POS_REPLACE;
  register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

  pass_info.pass = &pass_rtl_null.pass;
  pass_info.reference_pass_name = "*clean_state";
  pass_info.ref_pass_instance_number = 0;
  pass_info.pos_op = PASS_POS_REPLACE;
  register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);

  // Output pending state to the LLVM IR module, optimize and codegen once the
  // compilation unit has been completely processed.
  register_callback(plugin_name, PLUGIN_FINISH_UNIT, llvm_finish_unit, NULL);

  // Run shutdown code when GCC exits.
  register_callback(plugin_name, PLUGIN_FINISH, llvm_finish, NULL);

  return 0;
}
