//===----------- 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.DisableUnitAtATime = !flag_unit_at_a_time;
  PassBuilder.DisableUnrollLoops = !flag_unroll_loops;
//  Don't turn on the SLP vectorizer by default at -O3 for the moment.
//  PassBuilder.SLPVectorize = flag_tree_slp_vectorize;
  PassBuilder.LoopVectorize = flag_tree_vectorize;

  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;
}
