<commit_before>//===----------------------------------------------------------------------===//
// LLVM 'GCCAS' UTILITY
//
// This utility is designed to be used by the GCC frontend for creating bytecode
// files from its intermediate LLVM assembly.  The requirements for this utility
// are thus slightly different than that of the standard `as' util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoadValueNumbering.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/RaisePointerReferences.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

namespace {
  cl::opt<std::string>
  InputFilename(cl::Positional,cl::desc("<input llvm assembly>"),cl::init("-"));

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"),
                 cl::value_desc("filename"));

  cl::opt<int>
  RunNPasses("stopAfterNPasses",
             cl::desc("Only run the first N passes of gccas"), cl::Hidden,
             cl::value_desc("# passes"));

  cl::opt<bool>
  Verify("verify", cl::desc("Verify each pass result"));
}

static inline void addPass(PassManager &PM, Pass *P) {
  static int NumPassesCreated = 0;

  // If we haven't already created the number of passes that was requested...
  if (RunNPasses == 0 || RunNPasses > NumPassesCreated) {
    // Add the pass to the pass manager...
    PM.add(P);

    // If we are verifying all of the intermediate steps, add the verifier...
    if (Verify) PM.add(createVerifierPass());

    // Keep track of how many passes we made for -stopAfterNPasses
    ++NumPassesCreated;
  } else {
    delete P;             // We don't want this pass to run, just delete it now
  }
}

void AddConfiguredTransformationPasses(PassManager &PM) {
  PM.add(createVerifierPass());                  // Verify that input is correct
  addPass(PM, createFunctionResolvingPass());    // Resolve (...) functions
  addPass(PM, createGlobalDCEPass());            // Kill unused uinit g-vars
  addPass(PM, createDeadTypeEliminationPass());  // Eliminate dead types
  addPass(PM, createConstantMergePass());        // Merge dup global constants
  addPass(PM, createRaiseAllocationsPass());     // call %malloc -> malloc inst
  addPass(PM, createInstructionCombiningPass()); // Cleanup code for raise
  addPass(PM, createRaisePointerReferencesPass());// Recover type information
  addPass(PM, createTailDuplicationPass());      // Simplify cfg by copying code
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
  addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
  addPass(PM, createPromoteMemoryToRegister());  // Promote alloca's to regs
  addPass(PM, createIndVarSimplifyPass());       // Simplify indvars
  addPass(PM, createReassociatePass());          // Reassociate expressions
  // Kill corr branches
  //addPass(PM, createCorrelatedExpressionEliminationPass());
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createLICMPass());                 // Hoist loop invariants
  addPass(PM, createLoadValueNumberingPass());   // GVN for load instructions
  addPass(PM, createGCSEPass());                 // Remove common subexprs
  addPass(PM, createSCCPPass());                 // Constant prop with SCCP

  // Run instcombine after redundancy elimination to exploit opportunities
  // opened up by them.
  addPass(PM, createInstructionCombiningPass());
  addPass(PM, createAggressiveDCEPass());        // SSA based 'Aggressive DCE'
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
}

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    std::cerr << argv[0] << ": " << E.getMessage() << "\n";
    return 1;
  }

  if (M.get() == 0) {
    std::cerr << argv[0] << ": assembly didn't read correctly.\n";
    return 1;
  }

  std::ostream *Out = 0;
  if (OutputFilename == "") {   // Didn't specify an output filename?
    if (InputFilename == "-") {
      OutputFilename = "-";
    } else {
      std::string IFN = InputFilename;
      int Len = IFN.length();
      if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
        OutputFilename = std::string(IFN.begin(), IFN.end()-2);
      } else {
        OutputFilename = IFN;   // Append a .o to it
      }
      OutputFilename += ".o";
    }
  }

  if (OutputFilename == "-")
    Out = &std::cout;
  else {
    Out = new std::ofstream(OutputFilename.c_str(), std::ios::out);

    // Make sure that the Out file gets unlink'd from the disk if we get a
    // signal
    RemoveFileOnSignal(OutputFilename);
  }

  if (!Out->good()) {
    std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
    return 1;
  }

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;

  // Add an appropriate TargetData instance for this module...
  Passes.add(new TargetData("gccas", M.get()));

  // Add all of the transformation passes to the pass manager to do the cleanup
  // and optimization of the GCC output.
  //
  AddConfiguredTransformationPasses(Passes);

  // Write bytecode to file...
  Passes.add(new WriteBytecodePass(Out));

  // Run our queue of passes all at once now, efficiently.
  Passes.run(*M.get());

  if (Out != &std::cout) delete Out;
  return 0;
}
<commit_msg>Completely remove mention of the correlated branch elimination pass.  It has bugs and needs to be reworked anyway.<commit_after>//===----------------------------------------------------------------------===//
// LLVM 'GCCAS' UTILITY
//
// This utility is designed to be used by the GCC frontend for creating bytecode
// files from its intermediate LLVM assembly.  The requirements for this utility
// are thus slightly different than that of the standard `as' util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoadValueNumbering.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/RaisePointerReferences.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

namespace {
  cl::opt<std::string>
  InputFilename(cl::Positional,cl::desc("<input llvm assembly>"),cl::init("-"));

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"),
                 cl::value_desc("filename"));

  cl::opt<int>
  RunNPasses("stopAfterNPasses",
             cl::desc("Only run the first N passes of gccas"), cl::Hidden,
             cl::value_desc("# passes"));

  cl::opt<bool>
  Verify("verify", cl::desc("Verify each pass result"));
}

static inline void addPass(PassManager &PM, Pass *P) {
  static int NumPassesCreated = 0;

  // If we haven't already created the number of passes that was requested...
  if (RunNPasses == 0 || RunNPasses > NumPassesCreated) {
    // Add the pass to the pass manager...
    PM.add(P);

    // If we are verifying all of the intermediate steps, add the verifier...
    if (Verify) PM.add(createVerifierPass());

    // Keep track of how many passes we made for -stopAfterNPasses
    ++NumPassesCreated;
  } else {
    delete P;             // We don't want this pass to run, just delete it now
  }
}

void AddConfiguredTransformationPasses(PassManager &PM) {
  PM.add(createVerifierPass());                  // Verify that input is correct
  addPass(PM, createFunctionResolvingPass());    // Resolve (...) functions
  addPass(PM, createGlobalDCEPass());            // Kill unused uinit g-vars
  addPass(PM, createDeadTypeEliminationPass());  // Eliminate dead types
  addPass(PM, createConstantMergePass());        // Merge dup global constants
  addPass(PM, createRaiseAllocationsPass());     // call %malloc -> malloc inst
  addPass(PM, createInstructionCombiningPass()); // Cleanup code for raise
  addPass(PM, createRaisePointerReferencesPass());// Recover type information
  addPass(PM, createTailDuplicationPass());      // Simplify cfg by copying code
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
  addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
  addPass(PM, createPromoteMemoryToRegister());  // Promote alloca's to regs
  addPass(PM, createIndVarSimplifyPass());       // Simplify indvars
  addPass(PM, createReassociatePass());          // Reassociate expressions
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createLICMPass());                 // Hoist loop invariants
  addPass(PM, createLoadValueNumberingPass());   // GVN for load instructions
  addPass(PM, createGCSEPass());                 // Remove common subexprs
  addPass(PM, createSCCPPass());                 // Constant prop with SCCP

  // Run instcombine after redundancy elimination to exploit opportunities
  // opened up by them.
  addPass(PM, createInstructionCombiningPass());
  addPass(PM, createAggressiveDCEPass());        // SSA based 'Aggressive DCE'
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
}

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    std::cerr << argv[0] << ": " << E.getMessage() << "\n";
    return 1;
  }

  if (M.get() == 0) {
    std::cerr << argv[0] << ": assembly didn't read correctly.\n";
    return 1;
  }

  std::ostream *Out = 0;
  if (OutputFilename == "") {   // Didn't specify an output filename?
    if (InputFilename == "-") {
      OutputFilename = "-";
    } else {
      std::string IFN = InputFilename;
      int Len = IFN.length();
      if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
        OutputFilename = std::string(IFN.begin(), IFN.end()-2);
      } else {
        OutputFilename = IFN;   // Append a .o to it
      }
      OutputFilename += ".o";
    }
  }

  if (OutputFilename == "-")
    Out = &std::cout;
  else {
    Out = new std::ofstream(OutputFilename.c_str(), std::ios::out);

    // Make sure that the Out file gets unlink'd from the disk if we get a
    // signal
    RemoveFileOnSignal(OutputFilename);
  }

  if (!Out->good()) {
    std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
    return 1;
  }

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;

  // Add an appropriate TargetData instance for this module...
  Passes.add(new TargetData("gccas", M.get()));

  // Add all of the transformation passes to the pass manager to do the cleanup
  // and optimization of the GCC output.
  //
  AddConfiguredTransformationPasses(Passes);

  // Write bytecode to file...
  Passes.add(new WriteBytecodePass(Out));

  // Run our queue of passes all at once now, efficiently.
  Passes.run(*M.get());

  if (Out != &std::cout) delete Out;
  return 0;
}
<|endoftext|>


<commit_before>#include "HexagonOffload.h"
#include "IRMutator.h"
#include "Closure.h"
#include "Param.h"

namespace Halide {
namespace Internal {

using std::string;
using std::vector;

/////////////////////////////////////////////////////////////////////////////
class InjectHexagonRpc : public IRMutator {
    using IRMutator::visit;

public:
    Module device_code;

    InjectHexagonRpc() : device_code("hexagon", Target(Target::HexagonStandalone, Target::Hexagon, 32)) {}

    void visit(const For *loop) {
        if (loop->device_api == DeviceAPI::Hexagon) {
            std::string hex_name = "hex_" + loop->name;

            // Build a closure for the device code.
            // TODO: Should this move the body of the loop to Hexagon,
            // or the loop itself? Currently, this moves the loop itself.
            Closure c(loop);

            // Make an argument list, and generate a function in the device_code module.
            std::vector<Argument> args;
            for (const auto& i : c.buffers) {
                Argument::Kind kind = Argument::InputBuffer;
                if (i.second.write) {
                    kind = Argument::OutputBuffer;
                }
                args.push_back(Argument(i.first, kind, i.second.type, i.second.dimensions));
            }
            for (const auto& i : c.vars) {
                args.push_back(Argument(i.first, Argument::InputScalar, i.second, 0));
            }
            device_code.append(LoweredFunc(hex_name, args, loop, LoweredFunc::External));

            // Generate a call to hexagon_device_run.
            std::vector<Expr> params;
            params.push_back(user_context_value());
            params.push_back(hex_name);
            for (const auto& i : c.buffers) {
                params.push_back(Variable::make(Handle(), i.first + ".buffer"));
            }
            for (const auto& i : c.vars) {
                params.push_back(Variable::make(i.second, i.first));
            }

            stmt = Evaluate::make(Call::make(Int(32), "halide_hexagon_run", params, Call::Extern));
        } else {
            IRMutator::visit(loop);
        }
    }
};

Stmt inject_hexagon_rpc(Stmt s, std::vector<Module>& device_code) {
    InjectHexagonRpc injector;
    s = injector.mutate(s);
    device_code.push_back(injector.device_code);
    return s;
}

}

}
<commit_msg>Fix call to halide_hexagon_run to pass arguments as arrays.<commit_after>#include "HexagonOffload.h"
#include "IRMutator.h"
#include "Closure.h"
#include "Param.h"

namespace Halide {
namespace Internal {

using std::string;
using std::vector;

/////////////////////////////////////////////////////////////////////////////
class InjectHexagonRpc : public IRMutator {
    using IRMutator::visit;

public:
    Module device_code;

    InjectHexagonRpc() : device_code("hexagon", Target(Target::HexagonStandalone, Target::Hexagon, 32)) {}

    void visit(const For *loop) {
        if (loop->device_api == DeviceAPI::Hexagon) {
            std::string hex_name = "hex_" + loop->name;

            // Build a closure for the device code.
            // TODO: Should this move the body of the loop to Hexagon,
            // or the loop itself? Currently, this moves the loop itself.
            Closure c(loop);

            // Make an argument list, and generate a function in the device_code module.
            std::vector<Argument> args;
            for (const auto& i : c.buffers) {
                Argument::Kind kind = Argument::InputBuffer;
                if (i.second.write) {
                    kind = Argument::OutputBuffer;
                }
                args.push_back(Argument(i.first, kind, i.second.type, i.second.dimensions));
            }
            for (const auto& i : c.vars) {
                args.push_back(Argument(i.first, Argument::InputScalar, i.second, 0));
            }
            device_code.append(LoweredFunc(hex_name, args, loop, LoweredFunc::External));

            // Generate a call to hexagon_device_run.
            std::vector<Expr> arg_sizes;
            std::vector<Expr> arg_ptrs;
            std::vector<Expr> arg_is_buffer;

            for (const auto& i : c.buffers) {
                arg_sizes.push_back(Expr((size_t)sizeof(buffer_t*)));
                arg_ptrs.push_back(Variable::make(type_of<buffer_t *>(), i.first + ".buffer"));
                arg_is_buffer.push_back(Expr((uint8_t)true));
            }
            for (const auto& i : c.vars) {
                Expr arg = Variable::make(i.second, i.first);
                Expr arg_ptr = Call::make(type_of<void *>(), Call::make_struct, {arg}, Call::Intrinsic);

                arg_sizes.push_back(Expr((size_t)i.second.bytes()));
                arg_ptrs.push_back(arg_ptr);
                arg_is_buffer.push_back(Expr((uint8_t)false));
            }

            std::vector<Expr> params;
            params.push_back(user_context_value());
            params.push_back(hex_name);
            params.push_back(Call::make(type_of<size_t*>(), Call::make_struct, arg_sizes, Call::Intrinsic));
            params.push_back(Call::make(type_of<void**>(), Call::make_struct, arg_ptrs, Call::Intrinsic));
            params.push_back(Call::make(type_of<uint8_t*>(), Call::make_struct, arg_is_buffer, Call::Intrinsic));

            stmt = Evaluate::make(Call::make(Int(32), "halide_hexagon_run", params, Call::Extern));
        } else {
            IRMutator::visit(loop);
        }
    }
};

Stmt inject_hexagon_rpc(Stmt s, std::vector<Module>& device_code) {
    InjectHexagonRpc injector;
    s = injector.mutate(s);
    device_code.push_back(injector.device_code);
    return s;
}

}

}
<|endoftext|>


<commit_before>//===- gccld.cpp - LLVM 'ld' compatible linker ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility is intended to be compatible with GCC, and follows standard
// system 'ld' conventions.  As such, the default output file is ./a.out.
// Additionally, this program outputs a shell script that is used to invoke LLI
// to execute the program.  In this manner, the generated executable (a.out for
// example), is directly executable, whereas the bytecode file actually lives in
// the a.out.bc file generated by this program.  Also, Force is on by default.
//
// Note that if someone (or a script) deletes the executable program generated,
// the .bc file will be left around.  Considering that this is a temporary hack,
// I'm not too worried about this.
//
//===----------------------------------------------------------------------===//

#include "gccld.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "Support/CommandLine.h"
#include "Support/FileUtilities.h"
#include "Support/Signals.h"
#include "Support/SystemUtils.h"
#include <fstream>
#include <memory>

using namespace llvm;

namespace {
  cl::list<std::string>
  InputFilenames(cl::Positional, cl::desc("<input bytecode files>"),
                 cl::OneOrMore);

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"), cl::init("a.out"),
                 cl::value_desc("filename"));

  cl::opt<bool>
  Verbose("v", cl::desc("Print information about actions taken"));

  cl::list<std::string>
  LibPaths("L", cl::desc("Specify a library search path"), cl::Prefix,
           cl::value_desc("directory"));

  cl::list<std::string>
  Libraries("l", cl::desc("Specify libraries to link to"), cl::Prefix,
            cl::value_desc("library prefix"));

  cl::opt<bool>
  Strip("s", cl::desc("Strip symbol info from executable"));

  cl::opt<bool>
  NoInternalize("disable-internalize",
                cl::desc("Do not mark all symbols as internal"));
  cl::alias
  ExportDynamic("export-dynamic", cl::desc("Alias for -disable-internalize"),
                cl::aliasopt(NoInternalize));

  cl::opt<bool>
  LinkAsLibrary("link-as-library", cl::desc("Link the .bc files together as a"
                                            " library, not an executable"));
  cl::alias
  Relink("r", cl::desc("Alias for -link-as-library"),
         cl::aliasopt(LinkAsLibrary));

  cl::opt<bool>
  Native("native",
         cl::desc("Generate a native binary instead of a shell script"));

  // Compatibility options that are ignored but supported by LD
  cl::opt<std::string>
  CO3("soname", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<std::string>
  CO4("version-script", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<bool>
  CO5("eh-frame-hdr", cl::Hidden, cl::desc("Compatibility option: ignored"));
}

namespace llvm {

/// PrintAndReturn - Prints a message to standard error and returns a value
/// usable for an exit status.
///
/// Inputs:
///  progname - The name of the program (i.e. argv[0]).
///  Message  - The message to print to standard error.
///  Extra    - Extra information to print between the program name and thei
///             message.  It is optional.
///
/// Return value:
///  Returns a value that can be used as the exit status (i.e. for exit()).
///
int
PrintAndReturn(const char *progname,
               const std::string &Message,
               const std::string &Extra)
{
  std::cerr << progname << Extra << ": " << Message << "\n";
  return 1;
}

/// CopyEnv - This function takes an array of environment variables and makes a
/// copy of it.  This copy can then be manipulated any way the caller likes
/// without affecting the process's real environment.
///
/// Inputs:
///  envp - An array of C strings containing an environment.
///
/// Return value:
///  NULL - An error occurred.
///
///  Otherwise, a pointer to a new array of C strings is returned.  Every string
///  in the array is a duplicate of the one in the original array (i.e. we do
///  not copy the char *'s from one array to another).
///
char ** CopyEnv(char ** const envp) {
  // Count the number of entries in the old list;
  unsigned entries;   // The number of entries in the old environment list
  for (entries = 0; envp[entries] != NULL; entries++)
  {
    ;
  }

  // Add one more entry for the NULL pointer that ends the list.
  ++entries;

  // If there are no entries at all, just return NULL.
  if (entries == 0)
    return NULL;

  // Allocate a new environment list.
  char **newenv;
  if ((newenv = new (char *) [entries]) == NULL)
    return NULL;

  // Make a copy of the list.  Don't forget the NULL that ends the list.
  entries = 0;
  while (envp[entries] != NULL) {
    newenv[entries] = new char[strlen (envp[entries]) + 1];
    strcpy (newenv[entries], envp[entries]);
    ++entries;
  }
  newenv[entries] = NULL;

  return newenv;
}

/// RemoveEnv - Remove the specified environment variable from the environment
/// array.
///
/// Inputs:
///  name - The name of the variable to remove.  It cannot be NULL.
///  envp - The array of environment variables.  It cannot be NULL.
///
/// Notes:
///  This is mainly done because functions to remove items from the environment
///  are not available across all platforms.  In particular, Solaris does not
///  seem to have an unsetenv() function or a setenv() function (or they are
///  undocumented if they do exist).
///
void RemoveEnv(const char * name, char ** const envp) {
  for (unsigned index=0; envp[index] != NULL; index++) {
    // Find the first equals sign in the array and make it an EOS character.
    char *p = strchr (envp[index], '=');
    if (p == NULL)
      continue;
    else
      *p = '\0';

    // Compare the two strings.  If they are equal, zap this string.
    // Otherwise, restore it.
    if (!strcmp(name, envp[index]))
      *envp[index] = '\0';
    else
      *p = '=';
  }

  return;
}

} // End llvm namespace

int main(int argc, char **argv, char **envp) {
  cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");

  std::string ModuleID("gccld-output");
  std::auto_ptr<Module> Composite(new Module(ModuleID));

  // We always look first in the current directory when searching for libraries.
  LibPaths.insert(LibPaths.begin(), ".");

  // If the user specified an extra search path in their environment, respect
  // it.
  if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
    LibPaths.push_back(SearchPath);

  // Remove any consecutive duplicates of the same library...
  Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
                  Libraries.end());

  // Link in all of the files
  if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
    return 1; // Error already printed

  if (!LinkAsLibrary)
    LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
                  Verbose, Native);

  // Link in all of the libraries next...

  // Create the output file.
  std::string RealBytecodeOutput = OutputFilename;
  if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
  std::ofstream Out(RealBytecodeOutput.c_str());
  if (!Out.good())
    return PrintAndReturn(argv[0], "error opening '" + RealBytecodeOutput +
                                   "' for writing!");

  // Ensure that the bytecode file gets removed from the disk if we get a
  // SIGINT signal.
  RemoveFileOnSignal(RealBytecodeOutput);

  // Generate the bytecode file.
  if (GenerateBytecode(Composite.get(), Strip, !NoInternalize, &Out)) {
    Out.close();
    return PrintAndReturn(argv[0], "error generating bytecode");
  }

  // Close the bytecode file.
  Out.close();

  // If we are not linking a library, generate either a native executable
  // or a JIT shell script, depending upon what the user wants.
  if (!LinkAsLibrary) {
    // If the user wants to generate a native executable, compile it from the
    // bytecode file.
    //
    // Otherwise, create a script that will run the bytecode through the JIT.
    if (Native) {
      // Name of the Assembly Language output file
      std::string AssemblyFile = OutputFilename + ".s";

      // Mark the output files for removal if we get an interrupt.
      RemoveFileOnSignal(AssemblyFile);
      RemoveFileOnSignal(OutputFilename);

      // Determine the locations of the llc and gcc programs.
      std::string llc = FindExecutable("llc", argv[0]);
      std::string gcc = FindExecutable("gcc", argv[0]);
      if (llc.empty())
        return PrintAndReturn(argv[0], "Failed to find llc");

      if (gcc.empty())
        return PrintAndReturn(argv[0], "Failed to find gcc");

      // Generate an assembly language file for the bytecode.
      if (Verbose) std::cout << "Generating Assembly Code\n";
      GenerateAssembly(AssemblyFile, RealBytecodeOutput, llc, envp);
      if (Verbose) std::cout << "Generating Native Code\n";
      GenerateNative(OutputFilename, AssemblyFile, Libraries, LibPaths,
                     gcc, envp);

      // Remove the assembly language file.
      removeFile (AssemblyFile);
    } else {
      // Output the script to start the program...
      std::ofstream Out2(OutputFilename.c_str());
      if (!Out2.good())
        return PrintAndReturn(argv[0], "error opening '" + OutputFilename +
                                       "' for writing!");
      Out2 << "#!/bin/sh\nlli $0.bc $*\n";
      Out2.close();
    }

    // Make the script executable...
    MakeFileExecutable(OutputFilename);

    // Make the bytecode file readable and directly executable in LLEE as well
    MakeFileExecutable(RealBytecodeOutput);
    MakeFileReadable(RealBytecodeOutput);
  }

  return 0;
}
<commit_msg>When writing out the runner script, add -load=<lib> lines to pull in all the shared objects automagically, so it doesn't have to be done by hand.<commit_after>//===- gccld.cpp - LLVM 'ld' compatible linker ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility is intended to be compatible with GCC, and follows standard
// system 'ld' conventions.  As such, the default output file is ./a.out.
// Additionally, this program outputs a shell script that is used to invoke LLI
// to execute the program.  In this manner, the generated executable (a.out for
// example), is directly executable, whereas the bytecode file actually lives in
// the a.out.bc file generated by this program.  Also, Force is on by default.
//
// Note that if someone (or a script) deletes the executable program generated,
// the .bc file will be left around.  Considering that this is a temporary hack,
// I'm not too worried about this.
//
//===----------------------------------------------------------------------===//

#include "gccld.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "Support/CommandLine.h"
#include "Support/FileUtilities.h"
#include "Support/Signals.h"
#include "Support/SystemUtils.h"
#include <fstream>
#include <memory>

using namespace llvm;

namespace {
  cl::list<std::string>
  InputFilenames(cl::Positional, cl::desc("<input bytecode files>"),
                 cl::OneOrMore);

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"), cl::init("a.out"),
                 cl::value_desc("filename"));

  cl::opt<bool>
  Verbose("v", cl::desc("Print information about actions taken"));

  cl::list<std::string>
  LibPaths("L", cl::desc("Specify a library search path"), cl::Prefix,
           cl::value_desc("directory"));

  cl::list<std::string>
  Libraries("l", cl::desc("Specify libraries to link to"), cl::Prefix,
            cl::value_desc("library prefix"));

  cl::opt<bool>
  Strip("s", cl::desc("Strip symbol info from executable"));

  cl::opt<bool>
  NoInternalize("disable-internalize",
                cl::desc("Do not mark all symbols as internal"));
  cl::alias
  ExportDynamic("export-dynamic", cl::desc("Alias for -disable-internalize"),
                cl::aliasopt(NoInternalize));

  cl::opt<bool>
  LinkAsLibrary("link-as-library", cl::desc("Link the .bc files together as a"
                                            " library, not an executable"));
  cl::alias
  Relink("r", cl::desc("Alias for -link-as-library"),
         cl::aliasopt(LinkAsLibrary));

  cl::opt<bool>
  Native("native",
         cl::desc("Generate a native binary instead of a shell script"));

  // Compatibility options that are ignored but supported by LD
  cl::opt<std::string>
  CO3("soname", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<std::string>
  CO4("version-script", cl::Hidden, cl::desc("Compatibility option: ignored"));
  cl::opt<bool>
  CO5("eh-frame-hdr", cl::Hidden, cl::desc("Compatibility option: ignored"));
}

namespace llvm {

/// PrintAndReturn - Prints a message to standard error and returns a value
/// usable for an exit status.
///
/// Inputs:
///  progname - The name of the program (i.e. argv[0]).
///  Message  - The message to print to standard error.
///  Extra    - Extra information to print between the program name and thei
///             message.  It is optional.
///
/// Return value:
///  Returns a value that can be used as the exit status (i.e. for exit()).
///
int
PrintAndReturn(const char *progname,
               const std::string &Message,
               const std::string &Extra)
{
  std::cerr << progname << Extra << ": " << Message << "\n";
  return 1;
}

/// CopyEnv - This function takes an array of environment variables and makes a
/// copy of it.  This copy can then be manipulated any way the caller likes
/// without affecting the process's real environment.
///
/// Inputs:
///  envp - An array of C strings containing an environment.
///
/// Return value:
///  NULL - An error occurred.
///
///  Otherwise, a pointer to a new array of C strings is returned.  Every string
///  in the array is a duplicate of the one in the original array (i.e. we do
///  not copy the char *'s from one array to another).
///
char ** CopyEnv(char ** const envp) {
  // Count the number of entries in the old list;
  unsigned entries;   // The number of entries in the old environment list
  for (entries = 0; envp[entries] != NULL; entries++)
  {
    ;
  }

  // Add one more entry for the NULL pointer that ends the list.
  ++entries;

  // If there are no entries at all, just return NULL.
  if (entries == 0)
    return NULL;

  // Allocate a new environment list.
  char **newenv;
  if ((newenv = new (char *) [entries]) == NULL)
    return NULL;

  // Make a copy of the list.  Don't forget the NULL that ends the list.
  entries = 0;
  while (envp[entries] != NULL) {
    newenv[entries] = new char[strlen (envp[entries]) + 1];
    strcpy (newenv[entries], envp[entries]);
    ++entries;
  }
  newenv[entries] = NULL;

  return newenv;
}

/// RemoveEnv - Remove the specified environment variable from the environment
/// array.
///
/// Inputs:
///  name - The name of the variable to remove.  It cannot be NULL.
///  envp - The array of environment variables.  It cannot be NULL.
///
/// Notes:
///  This is mainly done because functions to remove items from the environment
///  are not available across all platforms.  In particular, Solaris does not
///  seem to have an unsetenv() function or a setenv() function (or they are
///  undocumented if they do exist).
///
void RemoveEnv(const char * name, char ** const envp) {
  for (unsigned index=0; envp[index] != NULL; index++) {
    // Find the first equals sign in the array and make it an EOS character.
    char *p = strchr (envp[index], '=');
    if (p == NULL)
      continue;
    else
      *p = '\0';

    // Compare the two strings.  If they are equal, zap this string.
    // Otherwise, restore it.
    if (!strcmp(name, envp[index]))
      *envp[index] = '\0';
    else
      *p = '=';
  }

  return;
}

} // End llvm namespace

int main(int argc, char **argv, char **envp) {
  cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");

  std::string ModuleID("gccld-output");
  std::auto_ptr<Module> Composite(new Module(ModuleID));

  // We always look first in the current directory when searching for libraries.
  LibPaths.insert(LibPaths.begin(), ".");

  // If the user specified an extra search path in their environment, respect
  // it.
  if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
    LibPaths.push_back(SearchPath);

  // Remove any consecutive duplicates of the same library...
  Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
                  Libraries.end());

  // Link in all of the files
  if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
    return 1; // Error already printed

  if (!LinkAsLibrary)
    LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
                  Verbose, Native);

  // Link in all of the libraries next...

  // Create the output file.
  std::string RealBytecodeOutput = OutputFilename;
  if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
  std::ofstream Out(RealBytecodeOutput.c_str());
  if (!Out.good())
    return PrintAndReturn(argv[0], "error opening '" + RealBytecodeOutput +
                                   "' for writing!");

  // Ensure that the bytecode file gets removed from the disk if we get a
  // SIGINT signal.
  RemoveFileOnSignal(RealBytecodeOutput);

  // Generate the bytecode file.
  if (GenerateBytecode(Composite.get(), Strip, !NoInternalize, &Out)) {
    Out.close();
    return PrintAndReturn(argv[0], "error generating bytecode");
  }

  // Close the bytecode file.
  Out.close();

  // If we are not linking a library, generate either a native executable
  // or a JIT shell script, depending upon what the user wants.
  if (!LinkAsLibrary) {
    // If the user wants to generate a native executable, compile it from the
    // bytecode file.
    //
    // Otherwise, create a script that will run the bytecode through the JIT.
    if (Native) {
      // Name of the Assembly Language output file
      std::string AssemblyFile = OutputFilename + ".s";

      // Mark the output files for removal if we get an interrupt.
      RemoveFileOnSignal(AssemblyFile);
      RemoveFileOnSignal(OutputFilename);

      // Determine the locations of the llc and gcc programs.
      std::string llc = FindExecutable("llc", argv[0]);
      std::string gcc = FindExecutable("gcc", argv[0]);
      if (llc.empty())
        return PrintAndReturn(argv[0], "Failed to find llc");

      if (gcc.empty())
        return PrintAndReturn(argv[0], "Failed to find gcc");

      // Generate an assembly language file for the bytecode.
      if (Verbose) std::cout << "Generating Assembly Code\n";
      GenerateAssembly(AssemblyFile, RealBytecodeOutput, llc, envp);
      if (Verbose) std::cout << "Generating Native Code\n";
      GenerateNative(OutputFilename, AssemblyFile, Libraries, LibPaths,
                     gcc, envp);

      // Remove the assembly language file.
      removeFile (AssemblyFile);
    } else {
      // Output the script to start the program...
      std::ofstream Out2(OutputFilename.c_str());
      if (!Out2.good())
        return PrintAndReturn(argv[0], "error opening '" + OutputFilename +
                                       "' for writing!");
      Out2 << "#!/bin/sh\nlli \\\n";
      // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib.
      LibPaths.push_back("/lib");
      LibPaths.push_back("/usr/lib");
      // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a
      // shared object at all! See RH 8: plain text.
      std::vector<std::string>::iterator libc =
        std::find(Libraries.begin(), Libraries.end(), "c");
      if (libc != Libraries.end()) Libraries.erase(libc);
      // List all the shared object (native) libraries this executable will need
      // on the command line, so that we don't have to do this manually!
      for (std::vector<std::string>::iterator i = Libraries.begin(),
             e = Libraries.end(); i != e; ++i) {
        std::string FullLibraryPath = FindLib(*i, LibPaths, true);
        if (!FullLibraryPath.empty())
          Out2 << "    -load=" << FullLibraryPath << " \\\n";
      }
      Out2 << "    $0.bc $*\n";
      Out2.close();
    }

    // Make the script executable...
    MakeFileExecutable(OutputFilename);

    // Make the bytecode file readable and directly executable in LLEE as well
    MakeFileExecutable(RealBytecodeOutput);
    MakeFileReadable(RealBytecodeOutput);
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "multiVolumes.h"

namespace cura
{

void carveMultipleVolumes(std::vector<Slicer*> &volumes, bool alternate_carve_order)
{
    //Go trough all the volumes, and remove the previous volume outlines from our own outline, so we never have overlapped areas.
    for (unsigned int volume_1_idx = 1; volume_1_idx < volumes.size(); volume_1_idx++)
    {
        Slicer& volume_1 = *volumes[volume_1_idx];
        if (volume_1.mesh->getSettingBoolean("infill_mesh")
            || volume_1.mesh->getSettingBoolean("anti_overhang_mesh")
            || volume_1.mesh->getSettingBoolean("support_mesh")
            )
        {
            continue;
        }
        for (unsigned int volume_2_idx = 0; volume_2_idx < volume_1_idx; volume_2_idx++)
        {
            Slicer& volume_2 = *volumes[volume_2_idx];
            if (volume_2.mesh->getSettingBoolean("infill_mesh")
                || volume_2.mesh->getSettingBoolean("anti_overhang_mesh")
                || volume_2.mesh->getSettingBoolean("support_mesh")
                )
            {
                continue;
            }
            if (!volume_1.mesh->getAABB().hit(volume_2.mesh->getAABB()))
            {
                continue;
            }
            for (unsigned int layerNr = 0; layerNr < volume_1.layers.size(); layerNr++)
            {
                SlicerLayer& layer1 = volume_1.layers[layerNr];
                SlicerLayer& layer2 = volume_2.layers[layerNr];
                if (alternate_carve_order && layerNr % 2 == 0)
                {
                    layer2.polygons = layer2.polygons.difference(layer1.polygons);
                }
                else
                {
                    layer1.polygons = layer1.polygons.difference(layer2.polygons);
                }
            }
        }
    }
}

//Expand each layer a bit and then keep the extra overlapping parts that overlap with other volumes.
//This generates some overlap in dual extrusion, for better bonding in touching parts.
void generateMultipleVolumesOverlap(std::vector<Slicer*> &volumes)
{
    if (volumes.size() < 2)
    {
        return;
    }

    int offset_to_merge_other_merged_volumes = 20;
    for (Slicer* volume : volumes)
    {
        int overlap = volume->mesh->getSettingInMicrons("multiple_mesh_overlap");
        if (volume->mesh->getSettingBoolean("infill_mesh")
            || volume->mesh->getSettingBoolean("anti_overhang_mesh")
            || volume->mesh->getSettingBoolean("support_mesh")
            || overlap == 0)
        {
            continue;
        }
        AABB3D aabb(volume->mesh->getAABB());
        aabb.expandXY(overlap); // expand to account for the case where two models and their bounding boxes are adjacent along the X or Y-direction
        for (unsigned int layer_nr = 0; layer_nr < volume->layers.size(); layer_nr++)
        {
            Polygons all_other_volumes;
            for (Slicer* other_volume : volumes)
            {
                if (other_volume->mesh->getSettingBoolean("infill_mesh")
                    || other_volume->mesh->getSettingBoolean("anti_overhang_mesh")
                    || other_volume->mesh->getSettingBoolean("support_mesh")
                    || !other_volume->mesh->getAABB().hit(aabb)
                    || other_volume == volume
                )
                {
                    continue;
                }
                SlicerLayer& other_volume_layer = other_volume->layers[layer_nr];
                all_other_volumes = all_other_volumes.unionPolygons(other_volume_layer.polygons.offset(offset_to_merge_other_merged_volumes));
            }

            SlicerLayer& volume_layer = volume->layers[layer_nr];
            volume_layer.polygons = volume_layer.polygons.unionPolygons(all_other_volumes.intersection(volume_layer.polygons.offset(overlap / 2)));
        }
    }
}

void MultiVolumes::carveCuttingMeshes(std::vector<Slicer*>& volumes, const std::vector<Mesh>& meshes)
{
    for (unsigned int carving_mesh_idx = 0; carving_mesh_idx < volumes.size(); carving_mesh_idx++)
    {
        const Mesh& cutting_mesh = meshes[carving_mesh_idx];
        if (!cutting_mesh.getSettingBoolean("cutting_mesh"))
        {
            continue;
        }
        Slicer& cutting_mesh_volume = *volumes[carving_mesh_idx];
        for (unsigned int layer_nr = 0; layer_nr < cutting_mesh_volume.layers.size(); layer_nr++)
        {
            Polygons& cutting_mesh_layer = cutting_mesh_volume.layers[layer_nr].polygons;
            Polygons new_outlines;
            for (unsigned int carved_mesh_idx = 0; carved_mesh_idx < volumes.size(); carved_mesh_idx++)
            {
                const Mesh& carved_mesh = meshes[carved_mesh_idx];
                if (carved_mesh_idx == carving_mesh_idx || carved_mesh.getSettingBoolean("cutting_mesh"))
                {
                    continue;
                }
                Slicer& carved_volume = *volumes[carved_mesh_idx];
                Polygons& carved_mesh_layer = carved_volume.layers[layer_nr].polygons;
                Polygons intersection = cutting_mesh_layer.intersection(carved_mesh_layer);
                new_outlines.add(intersection);
                carved_mesh_layer = carved_mesh_layer.difference(cutting_mesh_layer);
            }
            cutting_mesh_layer = new_outlines;
        }
    }
}

}//namespace cura
<commit_msg>fix: union polygons after cutting meshes (CURA-966)<commit_after>#include "multiVolumes.h"

namespace cura
{

void carveMultipleVolumes(std::vector<Slicer*> &volumes, bool alternate_carve_order)
{
    //Go trough all the volumes, and remove the previous volume outlines from our own outline, so we never have overlapped areas.
    for (unsigned int volume_1_idx = 1; volume_1_idx < volumes.size(); volume_1_idx++)
    {
        Slicer& volume_1 = *volumes[volume_1_idx];
        if (volume_1.mesh->getSettingBoolean("infill_mesh")
            || volume_1.mesh->getSettingBoolean("anti_overhang_mesh")
            || volume_1.mesh->getSettingBoolean("support_mesh")
            )
        {
            continue;
        }
        for (unsigned int volume_2_idx = 0; volume_2_idx < volume_1_idx; volume_2_idx++)
        {
            Slicer& volume_2 = *volumes[volume_2_idx];
            if (volume_2.mesh->getSettingBoolean("infill_mesh")
                || volume_2.mesh->getSettingBoolean("anti_overhang_mesh")
                || volume_2.mesh->getSettingBoolean("support_mesh")
                )
            {
                continue;
            }
            if (!volume_1.mesh->getAABB().hit(volume_2.mesh->getAABB()))
            {
                continue;
            }
            for (unsigned int layerNr = 0; layerNr < volume_1.layers.size(); layerNr++)
            {
                SlicerLayer& layer1 = volume_1.layers[layerNr];
                SlicerLayer& layer2 = volume_2.layers[layerNr];
                if (alternate_carve_order && layerNr % 2 == 0)
                {
                    layer2.polygons = layer2.polygons.difference(layer1.polygons);
                }
                else
                {
                    layer1.polygons = layer1.polygons.difference(layer2.polygons);
                }
            }
        }
    }
}

//Expand each layer a bit and then keep the extra overlapping parts that overlap with other volumes.
//This generates some overlap in dual extrusion, for better bonding in touching parts.
void generateMultipleVolumesOverlap(std::vector<Slicer*> &volumes)
{
    if (volumes.size() < 2)
    {
        return;
    }

    int offset_to_merge_other_merged_volumes = 20;
    for (Slicer* volume : volumes)
    {
        int overlap = volume->mesh->getSettingInMicrons("multiple_mesh_overlap");
        if (volume->mesh->getSettingBoolean("infill_mesh")
            || volume->mesh->getSettingBoolean("anti_overhang_mesh")
            || volume->mesh->getSettingBoolean("support_mesh")
            || overlap == 0)
        {
            continue;
        }
        AABB3D aabb(volume->mesh->getAABB());
        aabb.expandXY(overlap); // expand to account for the case where two models and their bounding boxes are adjacent along the X or Y-direction
        for (unsigned int layer_nr = 0; layer_nr < volume->layers.size(); layer_nr++)
        {
            Polygons all_other_volumes;
            for (Slicer* other_volume : volumes)
            {
                if (other_volume->mesh->getSettingBoolean("infill_mesh")
                    || other_volume->mesh->getSettingBoolean("anti_overhang_mesh")
                    || other_volume->mesh->getSettingBoolean("support_mesh")
                    || !other_volume->mesh->getAABB().hit(aabb)
                    || other_volume == volume
                )
                {
                    continue;
                }
                SlicerLayer& other_volume_layer = other_volume->layers[layer_nr];
                all_other_volumes = all_other_volumes.unionPolygons(other_volume_layer.polygons.offset(offset_to_merge_other_merged_volumes));
            }

            SlicerLayer& volume_layer = volume->layers[layer_nr];
            volume_layer.polygons = volume_layer.polygons.unionPolygons(all_other_volumes.intersection(volume_layer.polygons.offset(overlap / 2)));
        }
    }
}

void MultiVolumes::carveCuttingMeshes(std::vector<Slicer*>& volumes, const std::vector<Mesh>& meshes)
{
    for (unsigned int carving_mesh_idx = 0; carving_mesh_idx < volumes.size(); carving_mesh_idx++)
    {
        const Mesh& cutting_mesh = meshes[carving_mesh_idx];
        if (!cutting_mesh.getSettingBoolean("cutting_mesh"))
        {
            continue;
        }
        Slicer& cutting_mesh_volume = *volumes[carving_mesh_idx];
        for (unsigned int layer_nr = 0; layer_nr < cutting_mesh_volume.layers.size(); layer_nr++)
        {
            Polygons& cutting_mesh_layer = cutting_mesh_volume.layers[layer_nr].polygons;
            Polygons new_outlines;
            for (unsigned int carved_mesh_idx = 0; carved_mesh_idx < volumes.size(); carved_mesh_idx++)
            {
                const Mesh& carved_mesh = meshes[carved_mesh_idx];
                if (carved_mesh_idx == carving_mesh_idx || carved_mesh.getSettingBoolean("cutting_mesh"))
                {
                    continue;
                }
                Slicer& carved_volume = *volumes[carved_mesh_idx];
                Polygons& carved_mesh_layer = carved_volume.layers[layer_nr].polygons;
                Polygons intersection = cutting_mesh_layer.intersection(carved_mesh_layer);
                new_outlines.add(intersection);
                carved_mesh_layer = carved_mesh_layer.difference(cutting_mesh_layer);
            }
            cutting_mesh_layer = new_outlines.unionPolygons();
        }
    }
}

}//namespace cura
<|endoftext|>


<commit_before>#include "radial_solver.h"

namespace sirius {

int Radial_solver::integrate(int nr, int l, double enu, sirius::Spline<double>& ve, sirius::Spline<double>& mp,
                             std::vector<double>& p, std::vector<double>& dpdr, std::vector<double>& q,
                             std::vector<double>& dqdr)
{
    double alpha2 = 0.5 * pow((1 / speed_of_light), 2);
    if (!relativistic_) alpha2 = 0.0;

    double enu0 = 0.0;
    if (relativistic_) enu0 = enu;

    double ll2 = 0.5 * l * (l + 1);

    double x2 = radial_grid_[0];
    double x2inv = radial_grid_.rinv(0);
    double v2 = ve[0] + zn_ / x2;
    double m2 = 1 - (v2 - enu0) * alpha2;

    p.resize(nr);
    dpdr.resize(nr);
    q.resize(nr);
    dqdr.resize(nr);

    // TODO: check r->0 asymptotic
    p[0] = pow(radial_grid_[0], l + 1) * exp(zn_ * radial_grid_[0] / (l + 1));
    q[0] = (0.5 / m2) * p[0] * (l / radial_grid_[0] + zn_ / (l + 1));

    double p2 = p[0];
    double q2 = q[0];
    double mp2 = mp[0];
    double vl2 = ll2 / m2 / pow(x2, 2);

    double v2enuvl2 = (v2 - enu + vl2);

    double pk[4];
    double qk[4];

    for (int i = 0; i < nr - 1; i++)
    {
        double x0 = x2;
        x2 = radial_grid_[i + 1];
        double x0inv = x2inv;
        x2inv = radial_grid_.rinv(i + 1);
        double h = radial_grid_.dr(i);
        double h1 = h / 2;

        double x1 = x0 + h1;
        double x1inv = 1.0 / x1;
        double p0 = p2;
        double q0 = q2;
        double m0 = m2;
        v2 = ve[i + 1] + zn_ * x2inv;

        double mp0 = mp2;
        mp2 = mp[i + 1];
        double mp1 = mp(i, h1);
        double v1 = ve(i, h1) + zn_ * x1inv;
        double m1 = 1 - (v1 - enu0) * alpha2;
        m2 = 1 - (v2 - enu0) * alpha2;
        vl2 = ll2 / m2 / pow(x2, 2);

        double v0enuvl0 = v2enuvl2;
        v2enuvl2 = (v2 - enu + vl2);

        double vl1 = ll2 / m1 / pow(x1, 2);

        double v1enuvl1 = (v1 - enu + vl1);

        // k0 = F(Y(x), x)
        pk[0] = 2 * m0 * q0 + p0 * x0inv;
        qk[0] = v0enuvl0 * p0 - q0 * x0inv - mp0;

        // k1 = F(Y(x) + k0 * h/2, x + h/2)
        pk[1] = 2 * m1 * (q0 + qk[0] * h1) + (p0 + pk[0] * h1) * x1inv;
        qk[1] = v1enuvl1 * (p0 + pk[0] * h1) - (q0 + qk[0] * h1) * x1inv - mp1;

        // k2 = F(Y(x) + k1 * h/2, x + h/2)
        pk[2] = 2 * m1 * (q0 + qk[1] * h1) + (p0 + pk[1] * h1) * x1inv;
        qk[2] = v1enuvl1 * (p0 + pk[1] * h1) - (q0 + qk[1] * h1) * x1inv - mp1;

        // k3 = F(Y(x) + k2 * h, x + h)
        pk[3] = 2 * m2 * (q0 + qk[2] * h) + (p0 + pk[2] * h) * x2inv;
        qk[3] = v2enuvl2 * (p0 + pk[2] * h) - (q0 + qk[2] * h) * x2inv - mp2;

        // Y(x + h) = Y(x) + h * (k0 + 2 * k1 + 2 * k2 + k3) / 6
        p2 = p0 + (pk[0] + 2 * (pk[1] + pk[2]) + pk[3]) * h / 6.0;
        q2 = q0 + (qk[0] + 2 * (qk[1] + qk[2]) + qk[3]) * h / 6.0;

        p2 = std::max(std::min(1e10, p2), -1e10);
        q2 = std::max(std::min(1e10, q2), -1e10);

        p[i + 1] = p2;
        q[i + 1] = q2;
    }

    int nn = 0;
    for (int i = 0; i < nr - 1; i++) if (p[i] * p[i + 1] < 0.0) nn++;

    for (int i = 0; i < nr; i++)
    {
        double V = ve[i] + zn_ * radial_grid_.rinv(i);
        double M = 1.0 - (V - enu0) * alpha2;

        // P' = 2MQ + \frac{P}{r}
        dpdr[i] = 2 * M * q[i] + p[i] * radial_grid_.rinv(i);

        // Q' = (V - E + \frac{\ell(\ell + 1)}{2 M r^2}) P - \frac{Q}{r}
        dqdr[i] = (V - enu + double(l * (l + 1)) / (2 * M * pow(radial_grid_[i], 2))) * p[i] -
                  q[i] * radial_grid_.rinv(i) - mp[i];
    }

    return nn;
}

double Radial_solver::find_enu(int n, int l, std::vector<double>& v, double enu0)
{
    std::vector<double> p;
    std::vector<double> hp;

    double enu = enu0;
    double de = 0.001;
    bool found = false;
    double dpdr;
    int nndp = 0;
    for (int i = 0; i < 1000; i++)
    {
        int nnd = solve_in_mt(l, enu, 0, v, p, hp, dpdr) - (n - l - 1);
        if (nnd > 0)
        {
            enu -= de;
        }
        else
        {
            enu += de;
        }
        if (i > 0)
        {
            if (nnd != nndp)
            {
                de *= 0.5;
            }
            else
            {
                de *= 1.25;
            }
        }
        nndp = nnd;
        if (fabs(de) < 1e-10)
        {
            found = true;
            break;
        }
    }
    if (!found)
    {
        error_local(__FILE__, __LINE__, "top of the band is not found");
    }
    double etop = enu;
    de = -0.001;
    found = false;
    double p1p = 0;
    for (int i = 0; i < 1000; i++)
    {
        solve_in_mt(l, enu, 0, v, p, hp, dpdr);

        if (i > 0)
        {
            if (dpdr * p1p < 0.0)
            {
                if (fabs(de) < 1e-10)
                {
                    found = true;
                    break;
                }
                de *= -0.5;
            }
            else
            {
                de *= 1.25;
            }
        }
        p1p = dpdr;
        enu += de;
    }
    if (!found)
    {
        error_local(__FILE__, __LINE__, "bottom of the band is not found");
    }
    return (enu + etop) / 2.0;
}

int Radial_solver::solve_in_mt(int l, double enu, int m, std::vector<double>& v, std::vector<double>& p,
                               std::vector<double>& hp, double& dpdr_R)
{
    std::vector<double> ve(radial_grid_.num_mt_points());
    for (int i = 0; i < radial_grid_.num_mt_points(); i++) ve[i] = v[i] - zn_ / radial_grid_[i];

    sirius::Spline<double> ve_spline(radial_grid_.num_mt_points(), radial_grid_, ve);

    sirius::Spline<double> mp_spline(radial_grid_.num_mt_points(), radial_grid_);

    std::vector<double> q;
    std::vector<double> dpdr;
    std::vector<double> dqdr;

    int nn = 0;

    for (int j = 0; j <= m; j++)
    {
        if (j)
        {
            for (int i = 0; i < radial_grid_.num_mt_points(); i++) mp_spline[i] = j * p[i];

            mp_spline.interpolate();
        }

        nn = integrate(radial_grid_.num_mt_points(), l, enu, ve_spline, mp_spline, p, dpdr, q, dqdr);
    }

    hp.resize(radial_grid_.num_mt_points());
    double alph2 = 0.0;
    if (relativistic_) alph2 = pow((1.0 / speed_of_light), 2);
    for (int i = 0; i < radial_grid_.num_mt_points(); i++)
    {
        double t1 = 2.0 - v[i] * alph2;
        hp[i] = (double(l * (l + 1)) / t1 / pow(radial_grid_[i], 2.0) + v[i]) * p[i] - q[i] / radial_grid_[i] - dqdr[i];
    }
    dpdr_R = dpdr[radial_grid_.num_mt_points() - 1];
    return nn;
}

int Radial_solver::solve_in_mt(int l, double enu, int m, std::vector<double>& v, std::vector<double>& p0,
                               std::vector<double>& p1, std::vector<double>& q0, std::vector<double>& q1)
{
    std::vector<double> ve(radial_grid_.num_mt_points());
    for (int i = 0; i < radial_grid_.num_mt_points(); i++) ve[i] = v[i] - zn_ / radial_grid_[i];

    sirius::Spline<double> ve_spline(radial_grid_.num_mt_points(), radial_grid_, ve);

    sirius::Spline<double> mp_spline(radial_grid_.num_mt_points(), radial_grid_);

    int nn = 0;

    for (int j = 0; j <= m; j++)
    {
        if (j)
        {
            for (int i = 0; i < radial_grid_.num_mt_points(); i++) mp_spline[i] = j * p0[i];

            mp_spline.interpolate();
        }

        nn = integrate(radial_grid_.num_mt_points(), l, enu, ve_spline, mp_spline, p0, p1, q0, q1);
    }

    return nn;
}

void Radial_solver::bound_state(int n, int l, std::vector<double>& v, double& enu, std::vector<double>& p)
{
    std::vector<double> ve(radial_grid_.size());
    for (int i = 0; i < radial_grid_.size(); i++) ve[i] = v[i] - zn_ / radial_grid_[i];

    sirius::Spline<double> ve_spline(radial_grid_.size(), radial_grid_, ve);
    sirius::Spline<double> mp_spline(radial_grid_.size(), radial_grid_);

    std::vector<double> q(radial_grid_.size());
    std::vector<double> dpdr(radial_grid_.size());
    std::vector<double> dqdr(radial_grid_.size());

    int s = 1;
    int sp;
    double denu = enu_tolerance_;

    for (int iter = 0; iter < 1000; iter++)
    {
        int nn = integrate(radial_grid_.size(), l, enu, ve_spline, mp_spline, p, dpdr, q, dqdr);

        sp = s;
        s = (nn > (n - l - 1)) ? -1 : 1;
        denu = s * fabs(denu);
        denu = (s != sp) ? denu * 0.5 : denu * 1.25;
        enu += denu;

        if (fabs(denu) < enu_tolerance_ && iter > 4) break;
    }

    if (fabs(denu) >= enu_tolerance_)
    {
        std::stringstream s;
        s << "enu is not converged for n = " << n << " and l = " << l;
        error_local(__FILE__, __LINE__, s);
    }

    // search for the turning point
    int idxtp = radial_grid_.size() - 1;
    for (int i = 0; i < radial_grid_.size(); i++)
    {
        if (v[i] > enu)
        {
            idxtp = i;
            break;
        }
    }

    // zero the tail of the wave-function
    double t1 = 1e100;
    for (int i = idxtp; i < radial_grid_.size(); i++)
    {
        if ((fabs(p[i]) < t1) && (p[i - 1] * p[i] > 0))
        {
            t1 = fabs(p[i]);
        }
        else
        {
            t1 = 0.0;
            p[i] = 0.0;
        }
    }

    std::vector<double> rho(radial_grid_.size());
    for (int i = 0; i < radial_grid_.size(); i++) rho[i] = p[i] * p[i];

    double norm = sirius::Spline<double>(radial_grid_.size(), radial_grid_, rho).integrate();

    for (int i = 0; i < radial_grid_.size(); i++) p[i] /= sqrt(norm);

    // count number of nodes
    int nn = 0;
    for (int i = 0; i < radial_grid_.size() - 1; i++) if (p[i] * p[i + 1] < 0.0) nn++;

    if (nn != (n - l - 1))
    {
        std::stringstream s;
        s << "n = " << n << std::endl
          << "l = " << l << std::endl
          << "enu = " << enu << std::endl
          << "wrong number of nodes : " << nn << " instead of " << (n - l - 1);
        error_local(__FILE__, __LINE__, s);
    }
}

}

<commit_msg>size->num_points name change<commit_after>#include "radial_solver.h"

namespace sirius {

int Radial_solver::integrate(int nr, int l, double enu, sirius::Spline<double>& ve, sirius::Spline<double>& mp,
                             std::vector<double>& p, std::vector<double>& dpdr, std::vector<double>& q,
                             std::vector<double>& dqdr)
{
    double alpha2 = 0.5 * pow((1 / speed_of_light), 2);
    if (!relativistic_) alpha2 = 0.0;

    double enu0 = 0.0;
    if (relativistic_) enu0 = enu;

    double ll2 = 0.5 * l * (l + 1);

    double x2 = radial_grid_[0];
    double x2inv = radial_grid_.rinv(0);
    double v2 = ve[0] + zn_ / x2;
    double m2 = 1 - (v2 - enu0) * alpha2;

    p.resize(nr);
    dpdr.resize(nr);
    q.resize(nr);
    dqdr.resize(nr);

    // TODO: check r->0 asymptotic
    p[0] = pow(radial_grid_[0], l + 1) * exp(zn_ * radial_grid_[0] / (l + 1));
    q[0] = (0.5 / m2) * p[0] * (l / radial_grid_[0] + zn_ / (l + 1));

    double p2 = p[0];
    double q2 = q[0];
    double mp2 = mp[0];
    double vl2 = ll2 / m2 / pow(x2, 2);

    double v2enuvl2 = (v2 - enu + vl2);

    double pk[4];
    double qk[4];

    for (int i = 0; i < nr - 1; i++)
    {
        double x0 = x2;
        x2 = radial_grid_[i + 1];
        double x0inv = x2inv;
        x2inv = radial_grid_.rinv(i + 1);
        double h = radial_grid_.dr(i);
        double h1 = h / 2;

        double x1 = x0 + h1;
        double x1inv = 1.0 / x1;
        double p0 = p2;
        double q0 = q2;
        double m0 = m2;
        v2 = ve[i + 1] + zn_ * x2inv;

        double mp0 = mp2;
        mp2 = mp[i + 1];
        double mp1 = mp(i, h1);
        double v1 = ve(i, h1) + zn_ * x1inv;
        double m1 = 1 - (v1 - enu0) * alpha2;
        m2 = 1 - (v2 - enu0) * alpha2;
        vl2 = ll2 / m2 / pow(x2, 2);

        double v0enuvl0 = v2enuvl2;
        v2enuvl2 = (v2 - enu + vl2);

        double vl1 = ll2 / m1 / pow(x1, 2);

        double v1enuvl1 = (v1 - enu + vl1);

        // k0 = F(Y(x), x)
        pk[0] = 2 * m0 * q0 + p0 * x0inv;
        qk[0] = v0enuvl0 * p0 - q0 * x0inv - mp0;

        // k1 = F(Y(x) + k0 * h/2, x + h/2)
        pk[1] = 2 * m1 * (q0 + qk[0] * h1) + (p0 + pk[0] * h1) * x1inv;
        qk[1] = v1enuvl1 * (p0 + pk[0] * h1) - (q0 + qk[0] * h1) * x1inv - mp1;

        // k2 = F(Y(x) + k1 * h/2, x + h/2)
        pk[2] = 2 * m1 * (q0 + qk[1] * h1) + (p0 + pk[1] * h1) * x1inv;
        qk[2] = v1enuvl1 * (p0 + pk[1] * h1) - (q0 + qk[1] * h1) * x1inv - mp1;

        // k3 = F(Y(x) + k2 * h, x + h)
        pk[3] = 2 * m2 * (q0 + qk[2] * h) + (p0 + pk[2] * h) * x2inv;
        qk[3] = v2enuvl2 * (p0 + pk[2] * h) - (q0 + qk[2] * h) * x2inv - mp2;

        // Y(x + h) = Y(x) + h * (k0 + 2 * k1 + 2 * k2 + k3) / 6
        p2 = p0 + (pk[0] + 2 * (pk[1] + pk[2]) + pk[3]) * h / 6.0;
        q2 = q0 + (qk[0] + 2 * (qk[1] + qk[2]) + qk[3]) * h / 6.0;

        p2 = std::max(std::min(1e10, p2), -1e10);
        q2 = std::max(std::min(1e10, q2), -1e10);

        p[i + 1] = p2;
        q[i + 1] = q2;
    }

    int nn = 0;
    for (int i = 0; i < nr - 1; i++) if (p[i] * p[i + 1] < 0.0) nn++;

    for (int i = 0; i < nr; i++)
    {
        double V = ve[i] + zn_ * radial_grid_.rinv(i);
        double M = 1.0 - (V - enu0) * alpha2;

        // P' = 2MQ + \frac{P}{r}
        dpdr[i] = 2 * M * q[i] + p[i] * radial_grid_.rinv(i);

        // Q' = (V - E + \frac{\ell(\ell + 1)}{2 M r^2}) P - \frac{Q}{r}
        dqdr[i] = (V - enu + double(l * (l + 1)) / (2 * M * pow(radial_grid_[i], 2))) * p[i] -
                  q[i] * radial_grid_.rinv(i) - mp[i];
    }

    return nn;
}

double Radial_solver::find_enu(int n, int l, std::vector<double>& v, double enu0)
{
    std::vector<double> p;
    std::vector<double> hp;

    double enu = enu0;
    double de = 0.001;
    bool found = false;
    double dpdr;
    int nndp = 0;
    for (int i = 0; i < 1000; i++)
    {
        int nnd = solve_in_mt(l, enu, 0, v, p, hp, dpdr) - (n - l - 1);
        if (nnd > 0)
        {
            enu -= de;
        }
        else
        {
            enu += de;
        }
        if (i > 0)
        {
            if (nnd != nndp)
            {
                de *= 0.5;
            }
            else
            {
                de *= 1.25;
            }
        }
        nndp = nnd;
        if (fabs(de) < 1e-10)
        {
            found = true;
            break;
        }
    }
    if (!found)
    {
        error_local(__FILE__, __LINE__, "top of the band is not found");
    }
    double etop = enu;
    de = -0.001;
    found = false;
    double p1p = 0;
    for (int i = 0; i < 1000; i++)
    {
        solve_in_mt(l, enu, 0, v, p, hp, dpdr);

        if (i > 0)
        {
            if (dpdr * p1p < 0.0)
            {
                if (fabs(de) < 1e-10)
                {
                    found = true;
                    break;
                }
                de *= -0.5;
            }
            else
            {
                de *= 1.25;
            }
        }
        p1p = dpdr;
        enu += de;
    }
    if (!found)
    {
        error_local(__FILE__, __LINE__, "bottom of the band is not found");
    }
    return (enu + etop) / 2.0;
}

int Radial_solver::solve_in_mt(int l, double enu, int m, std::vector<double>& v, std::vector<double>& p,
                               std::vector<double>& hp, double& dpdr_R)
{
    std::vector<double> ve(radial_grid_.num_mt_points());
    for (int i = 0; i < radial_grid_.num_mt_points(); i++) ve[i] = v[i] - zn_ / radial_grid_[i];

    sirius::Spline<double> ve_spline(radial_grid_.num_mt_points(), radial_grid_, ve);

    sirius::Spline<double> mp_spline(radial_grid_.num_mt_points(), radial_grid_);

    std::vector<double> q;
    std::vector<double> dpdr;
    std::vector<double> dqdr;

    int nn = 0;

    for (int j = 0; j <= m; j++)
    {
        if (j)
        {
            for (int i = 0; i < radial_grid_.num_mt_points(); i++) mp_spline[i] = j * p[i];

            mp_spline.interpolate();
        }

        nn = integrate(radial_grid_.num_mt_points(), l, enu, ve_spline, mp_spline, p, dpdr, q, dqdr);
    }

    hp.resize(radial_grid_.num_mt_points());
    double alph2 = 0.0;
    if (relativistic_) alph2 = pow((1.0 / speed_of_light), 2);
    for (int i = 0; i < radial_grid_.num_mt_points(); i++)
    {
        double t1 = 2.0 - v[i] * alph2;
        hp[i] = (double(l * (l + 1)) / t1 / pow(radial_grid_[i], 2.0) + v[i]) * p[i] - q[i] / radial_grid_[i] - dqdr[i];
    }
    dpdr_R = dpdr[radial_grid_.num_mt_points() - 1];
    return nn;
}

int Radial_solver::solve_in_mt(int l, double enu, int m, std::vector<double>& v, std::vector<double>& p0,
                               std::vector<double>& p1, std::vector<double>& q0, std::vector<double>& q1)
{
    std::vector<double> ve(radial_grid_.num_mt_points());
    for (int i = 0; i < radial_grid_.num_mt_points(); i++) ve[i] = v[i] - zn_ / radial_grid_[i];

    sirius::Spline<double> ve_spline(radial_grid_.num_mt_points(), radial_grid_, ve);

    sirius::Spline<double> mp_spline(radial_grid_.num_mt_points(), radial_grid_);

    int nn = 0;

    for (int j = 0; j <= m; j++)
    {
        if (j)
        {
            for (int i = 0; i < radial_grid_.num_mt_points(); i++) mp_spline[i] = j * p0[i];

            mp_spline.interpolate();
        }

        nn = integrate(radial_grid_.num_mt_points(), l, enu, ve_spline, mp_spline, p0, p1, q0, q1);
    }

    return nn;
}

void Radial_solver::bound_state(int n, int l, std::vector<double>& v, double& enu, std::vector<double>& p)
{
    int np = radial_grid_.num_points();

    std::vector<double> ve(np);
    for (int i = 0; i < np; i++) ve[i] = v[i] - zn_ / radial_grid_[i];

    sirius::Spline<double> ve_spline(np, radial_grid_, ve);
    sirius::Spline<double> mp_spline(np, radial_grid_);

    std::vector<double> q(np);
    std::vector<double> dpdr(np);
    std::vector<double> dqdr(np);

    int s = 1;
    int sp;
    double denu = enu_tolerance_;

    for (int iter = 0; iter < 1000; iter++)
    {
        int nn = integrate(np, l, enu, ve_spline, mp_spline, p, dpdr, q, dqdr);

        sp = s;
        s = (nn > (n - l - 1)) ? -1 : 1;
        denu = s * fabs(denu);
        denu = (s != sp) ? denu * 0.5 : denu * 1.25;
        enu += denu;

        if (fabs(denu) < enu_tolerance_ && iter > 4) break;
    }

    if (fabs(denu) >= enu_tolerance_)
    {
        std::stringstream s;
        s << "enu is not converged for n = " << n << " and l = " << l;
        error_local(__FILE__, __LINE__, s);
    }

    // search for the turning point
    int idxtp = np - 1;
    for (int i = 0; i < np; i++)
    {
        if (v[i] > enu)
        {
            idxtp = i;
            break;
        }
    }

    // zero the tail of the wave-function
    double t1 = 1e100;
    for (int i = idxtp; i < np; i++)
    {
        if ((fabs(p[i]) < t1) && (p[i - 1] * p[i] > 0))
        {
            t1 = fabs(p[i]);
        }
        else
        {
            t1 = 0.0;
            p[i] = 0.0;
        }
    }

    std::vector<double> rho(np);
    for (int i = 0; i < np; i++) rho[i] = p[i] * p[i];

    double norm = sirius::Spline<double>(np, radial_grid_, rho).integrate();

    for (int i = 0; i < np; i++) p[i] /= sqrt(norm);

    // count number of nodes
    int nn = 0;
    for (int i = 0; i < np - 1; i++) if (p[i] * p[i + 1] < 0.0) nn++;

    if (nn != (n - l - 1))
    {
        std::stringstream s;
        s << "n = " << n << std::endl
          << "l = " << l << std::endl
          << "enu = " << enu << std::endl
          << "wrong number of nodes : " << nn << " instead of " << (n - l - 1);
        error_local(__FILE__, __LINE__, s);
    }
}

}

<|endoftext|>


<commit_before>#include "caixa.h"

COORD const MAX = { 120, 60 };// ?
BOOL OR(BOOL A, BOOL B) { return (A || B); }
BOOL NOR(BOOL A, BOOL B) { return (!A && !B); }// return !OR(A, B); }//
BOOL AND(BOOL A, BOOL B) { return (A && B); }
BOOL NAND(BOOL A, BOOL B) { return (!A || !B); }//return !AND(A, B); };//

// Caixas
//-------

Caixas &Caixas::caixa(COORD pos, short width, short height, char ch, WORD attr)
{
    // validar a caixa
    if (NOR(pos.X < 0, pos.Y < 0) && // não tem coordenadas negativas
        NOR(pos.X > _max.X, pos.Y > _max.Y)) { // não tem coordenadas maiores que _max
        _caixas.push_back(Caixa(pos, width, height, ch, attr));
    }

    return *this;
}

// devolve (iterador da) caixa na posição pos (do mapa)
vector<Caixa>::iterator Caixas::caixa(COORD pos)
{
    vector<Caixa>::iterator it = _caixas.begin();
    for (it; it != _caixas.end(); it++) {
        if (pos.X == it->pos().X && pos.Y == it->pos().Y) {
            return it;
        }
    }

    return it;
}

// devolve caixas definidas numa determinada zona
vector<Caixa> Caixas::caixas(COORD pos, short width, short height)
{
    vector<Caixa> caixas;
    for (Caixa caixa : _caixas) {
        // coordenada da caixa
        COORD P = caixa.pos();
        // dentro da zona
        if (NOR(P.X - pos.X < 0, P.X - pos.X > width) &&
            NOR(P.Y - pos.Y < 0, P.Y - pos.Y > height)) {
            caixas.push_back(caixa);
        }
    }
    return caixas;
}

// devolve ás caixas que comtêm um determinado ponto
vector<Caixa> Caixas::contem(COORD ponto)
{
    vector<Caixa> caixas;

    for (Caixa caixa : _caixas) {
        // coordenada da caixa
        COORD P = caixa.pos();
        COORD size = caixa.size();

        // dentro da caixa
        if (NOR(ponto.X - P.X < 0, ponto.X - P.X > size.X) &&
            NOR(ponto.Y - P.Y < 0, ponto.Y - P.Y > size.Y)) {
            caixas.push_back(caixa);
        }
    }
    return caixas;
}
<commit_msg>Update Caixa<commit_after>#include "caixa.h"

COORD const MAX = { 120, 60 };// ?
BOOL OR(BOOL A, BOOL B) { return (A || B); }
BOOL NOR(BOOL A, BOOL B) { return (!A && !B); }// return !OR(A, B); }//
BOOL AND(BOOL A, BOOL B) { return (A && B); }
BOOL NAND(BOOL A, BOOL B) { return (!A || !B); }//return !AND(A, B); };//

// Caixas
//-------

Caixas &Caixas::caixa(COORD pos, short width, short height, char ch, WORD attr)
{
    // validar a caixa
    if (NOR(pos.X < 0, pos.Y < 0) && // não tem coordenadas negativas
        NOR(pos.X > _max.X, pos.Y > _max.Y)) { // não tem coordenadas maiores que _max
        _caixas.push_back(Caixa(pos, width, height, ch, attr));
    }

    return *this;
}

// devolve (iterador da) caixa na posição pos (do mapa)
vector<Caixa>::iterator Caixas::caixa(COORD pos)
{
    vector<Caixa>::iterator it = _caixas.begin();
    for (it; it != _caixas.end(); it++) {
        if (pos.X == it->pos().X && pos.Y == it->pos().Y) {
            return it;
        }
    }

    return it;
}

// devolve caixas definidas numa determinada zona
vector<Caixa> Caixas::caixas(COORD pos, short width, short height)
{
    vector<Caixa> caixas;

    for (Caixa caixa : _caixas) {
        // cantos da caixa
        COORD P[4];
        P[0] = caixa.pos();
        P[1] = { P[0].X, P[0].Y + caixa.height() - 1 };
        P[2] = { P[0].X + caixa.width() - 1, P[0].Y };
        P[3] = { P[0].X + caixa.width() - 1, P[0].Y + caixa.height() - 1 };
        for (int i = 0; i < 4; i++) {
            // dentro da zona
            if (NOR(P[i].X - pos.X < 0, P[i].X - pos.X > width) &&
                NOR(P[i].Y - pos.Y < 0, P[i].Y - pos.Y > height)) {
                caixas.push_back(caixa);
                break;
            }
        }
    }

    return caixas;
}

// devolve ás caixas que comtêm um determinado ponto
vector<Caixa> Caixas::contem(COORD ponto)
{
    vector<Caixa> caixas;

    for (Caixa caixa : _caixas) {
        // coordenada da caixa
        COORD P = caixa.pos();
        COORD size = caixa.size();
        // dentro da caixa
        if (NOR(ponto.X - P.X < 0, ponto.X - P.X > size.X) &&
            NOR(ponto.Y - P.Y < 0, ponto.Y - P.Y > size.Y)) {
            caixas.push_back(caixa);
        }
    }

    return caixas;
}
<|endoftext|>


<commit_before>#include "llvm/ADT/APInt.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <iostream>
#include <fstream>

using namespace llvm;
using namespace std;

static LLVMContext C;
static IRBuilder<NoFolder> Builder(C);
static std::unique_ptr<Module> M = llvm::make_unique<Module>("calc", C);
static ifstream gInFile;
char gCurValue = -1;
int  gArgsLen = 6;
int  gLineNo = 1;
enum oper {ADD = 0, SUB, MUL, DIV, MOD};
bool debug = true;

Value* parseExpression();
void skipSpaces();

void usage(void) {
  printf("executable <input file.calc>\r\n");
  return;
}

bool openFile(int argc, char **argv) {
  if (argc < 2) {
    usage();
    return false;
  }
  gInFile.open (argv[1], ifstream::in);
  return true;
}

char getChar() {
  return gCurValue;
}

void nextChar(void) {
  if (!gInFile.eof()) {
    gCurValue = gInFile.get();
  } else {
    gCurValue = EOF;
  }
}

char getnextChar() {
  nextChar();
  return gCurValue;
}

bool accept(char c) {
  if (getChar() == c) {
    nextChar();
    return true;
  }
  return false;
}

bool check(char c) {
  if (getChar() == c) {
    return true;
  }
  return false;
}

string getContext() {
  string context;
  getline(gInFile, context);
  return context;
}

void printError(int lineno) {
  printf ("%d:Invalid statement at LineNo:%d:%d - %c%s",
           lineno,
           gLineNo, (int)gInFile.tellg(), getChar(), getContext().c_str());
  exit(0);
}

void printError(int lineno, const char *c) {
  printf("%d:Unable to compile due to error %s at Line: %d FilePosition:%d \r\n",
      lineno,
      c, gLineNo, (int)gInFile.tellg());
  printf("Remaining Code: %c%s", getChar(), getContext().c_str());
  exit(0);
}

void parseComment() {
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }
  while (getnextChar() != '\n');
  //Skip \n
  getnextChar();
  gLineNo++;
  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
}

Value* parseArgs() {
  char errmsg[50];
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }
  int i;
  //Move the pointer next to a
  getnextChar();
  for (i = 0; i < gArgsLen; i++) {
    if (accept('0' + (i - 0))) { //Change from int to char
      if (debug) {
        printf("Exit %s\r\n", __PRETTY_FUNCTION__);
      }
      return ConstantInt::get(Type::getInt64Ty(C), i);
    }
  }
  sprintf(errmsg, "Invalid argument (a%c) used in the program",
          getChar());
  printError(__LINE__, errmsg);
  return NULL;
}

//Guess this should return an LLVM object
Value* parseArithmeticOperation(char oper) {
  Value* result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  switch (oper) {
  case '+':
    result = Builder.CreateAdd(parseExpression(),
						  								 parseExpression(), "addtmp");
  case '-':
    result = Builder.CreateSub(parseExpression(),
						  								 parseExpression(), "subtmp");
  case '*':
    result = Builder.CreateMul(parseExpression(),
						  								 parseExpression(), "multmp");
  case '/':
    result = Builder.CreateSDiv(parseExpression(),
						  							    parseExpression(), "divtmp");
  case '%':
    result = Builder.CreateSRem(parseExpression(),
					  								 	  parseExpression(), "modtmp");
  default:
    printError(__LINE__, "Fatal error in compiler. Cannot reach here");
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parseNumber() {
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  int num = 0, count = 0;
  bool isNegative = false;
  char ch = getChar();

  if (ch == '-') {
    isNegative = true;
    ch = getnextChar();
  }
  while  ((ch >= '0') && (ch <= '9')) {
    num = (num * 10 * count++) + (0 + (ch - '0'));
    ch = getnextChar();
  }
  if (isNegative) {
    num = num * (-1);
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return ConstantInt::get(C, APInt(64, num));
}

Value* parseRelationalOperation() {
  Value* result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  if (accept('>')) {
    if (accept('=')) {
      //This is greater than equals
      result = Builder.CreateICmpSGE(parseExpression(),
                                     parseExpression(), "gethan");
    } else {
      //This is greater than
      result = Builder.CreateICmpSGT(parseExpression(),
                                     parseExpression(), "gthan");
    }
  } else if (accept('<')) {
    if (accept('=')) {
      //This is less than equals
      result = Builder.CreateICmpSLE(parseExpression(),
                                     parseExpression(), "lethan");
    } else {
      //This is less than
      result = Builder.CreateICmpSLT(parseExpression(),
                                     parseExpression(), "lthan");
    }
  } else if (accept('!') && accept('=')) {
    //This is not equal to
    result = Builder.CreateICmpNE(parseExpression(),
                                  parseExpression(), "ne");
  } else if (accept('=') && accept('=')) {
    //This is double equals
    result = Builder.CreateICmpEQ(parseExpression(),
                                  parseExpression(), "eq");
  } else {
    printError(__LINE__, "Invalid Relational Operator used");
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parseBoolExpression() {
  Value* result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  skipSpaces();

  char ch = getChar();

  if (accept('t') && accept('r') && accept('u') && accept('e')) {
    //Its a true condition
    result = ConstantInt::get(C, APInt(64, 1));
  } else if (accept('f') && accept('a') && accept('l')
      && accept('s') && accept('e')) {
    //Its a false condition
    result = ConstantInt::get(C, APInt(64, 0));
  } else if ((ch == '>') || (ch == '<') || (ch == '=') ||
             (ch == '!')) {
    result = parseRelationalOperation();
  } else if (ch == ('(')) {
    getnextChar();
    result = parseBoolExpression();
    if (accept(')') == false) {
      printError(__LINE__, "Missing ) Paranthesis in boolean exp");
    }
  } else {
    printError(__LINE__, "Boolean expression Missing");
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parseIf() {
  Value *result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  if (accept('i') && accept('f')) {
    result = Builder.CreateSelect(parseBoolExpression(),
                                  parseExpression(),
                                  parseExpression());
  } else {
    printError(__LINE__);
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

void skipSpaces() {
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  while (getChar() != EOF) {
    if (accept(' ')) {
      continue;
    } else if (accept('\n')) {
      gLineNo++;
      continue;
    }
    break;
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
}

Value* parseExpression() {
  char errmsg[75];
  Value *result;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  skipSpaces();

  char ch = getChar();

  do{
    if (ch == '#') {
      parseComment();
    } else if (ch == 'a') {
      result = parseArgs();
      break;
    } else if (ch == '\n') {
      //Increment the line number, so that we can give a
      //meaningful error message
      gLineNo++;
    } else if (ch == ' ') {
      //Ignore White space
    } else if ((ch == '+') || (ch == '-') || (ch == '*') ||
               (ch == '/') || (ch == '%')) {
      getnextChar();
      result = parseArithmeticOperation(ch);
      break;
    } else if (ch == '-') {
      result = parseNumber();
      break;
    } else if ((ch >= '0') && (ch <= '9')) {
      result = parseNumber();
      break;
    } else if (ch == '(') {
      getnextChar();
      result = parseExpression();
      if (accept(')') == false) {
        printError(__LINE__, "Missing Matching paranthesis");
      }
      break;
    } else if (ch == 'i') {
      result = parseIf();
      break;
    } else if (ch == ')') {
      getnextChar();
      break;
    } else {
      printError(__LINE__);
    }
    ch = getChar();
  }while (ch != EOF);

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parser() {
  Value *result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }
  char ch = getnextChar();
  while(ch != EOF) {
    if (ch == '#') {
      parseComment();
    } else {
      result = parseExpression();
      skipSpaces();
      if (getChar() == EOF) {
        break;
      } else {
        printError(__LINE__);
      }
    }
    ch = getChar();
  }
  printf("Parsed successfully\r\n");
  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

static int compile() {
  M->setTargetTriple(llvm::sys::getProcessTriple());
  std::vector<Type *> SixInts(6, Type::getInt64Ty(C));
  FunctionType *FT = FunctionType::get(Type::getInt64Ty(C), SixInts, false);
  Function *F = Function::Create(FT, Function::ExternalLinkage, "f", &*M);
  BasicBlock *BB = BasicBlock::Create(C, "entry", F);
  Builder.SetInsertPoint(BB);

  // TODO: parse the source program
  // TODO: generate correct LLVM instead of just an empty function

  Value *RetVal = ConstantInt::get(C, APInt(64, 0));
  Builder.CreateRet(RetVal);
  assert(!verifyModule(*M, &outs()));
  M->dump();
  return 0;
}

int main(int argc, char **argv) {
  if (openFile(argc, argv) == true) {
    parser();
    //return compile();
  }
  return -1;
}
<commit_msg>Adding the parsing code<commit_after>#include "llvm/ADT/APInt.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <iostream>
#include <fstream>

using namespace llvm;
using namespace std;

static LLVMContext C;
static IRBuilder<NoFolder> Builder(C);
static std::unique_ptr<Module> M = llvm::make_unique<Module>("calc", C);
static ifstream gInFile;
char gCurValue = -1;
int  gArgsLen = 6;
int  gLineNo = 1;
enum oper {ADD = 0, SUB, MUL, DIV, MOD};
bool debug = true;

Value* parseExpression();
void skipSpaces();

void usage(void) {
  printf("executable <input file.calc>\r\n");
  return;
}

bool openFile(int argc, char **argv) {
  if (argc < 2) {
    usage();
    return false;
  }
  gInFile.open (argv[1], ifstream::in);
  return true;
}

char getChar() {
  return gCurValue;
}

void nextChar(void) {
  if (!gInFile.eof()) {
    gCurValue = gInFile.get();
  } else {
    gCurValue = EOF;
  }
}

char getnextChar() {
  nextChar();
  return gCurValue;
}

bool accept(char c) {
  if (getChar() == c) {
    nextChar();
    return true;
  }
  return false;
}

bool check(char c) {
  if (getChar() == c) {
    return true;
  }
  return false;
}

string getContext() {
  string context;
  getline(gInFile, context);
  return context;
}

void printError(int lineno) {
  printf ("%d:Invalid statement at LineNo:%d:%d - %c%s",
           lineno,
           gLineNo, (int)gInFile.tellg(), getChar(), getContext().c_str());
  exit(0);
}

void printError(int lineno, const char *c) {
  printf("%d:Unable to compile due to error %s at Line: %d FilePosition:%d \r\n",
      lineno,
      c, gLineNo, (int)gInFile.tellg());
  printf("Remaining Code: %c%s", getChar(), getContext().c_str());
  exit(0);
}

void parseComment() {
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }
  while (getnextChar() != '\n');
  //Skip \n
  getnextChar();
  gLineNo++;
  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
}

Value* parseArgs() {
  char errmsg[50];
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }
  int i;
  //Move the pointer next to a
  getnextChar();
  for (i = 0; i < gArgsLen; i++) {
    if (accept('0' + (i - 0))) { //Change from int to char
      if (debug) {
        printf("Exit %s\r\n", __PRETTY_FUNCTION__);
      }
      return ConstantInt::get(Type::getInt64Ty(C), i);
    }
  }
  sprintf(errmsg, "Invalid argument (a%c) used in the program",
          getChar());
  printError(__LINE__, errmsg);
  return NULL;
}

//Guess this should return an LLVM object
Value* parseArithmeticOperation(char oper) {
  Value* result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  switch (oper) {
  case '+':
    result = Builder.CreateAdd(parseExpression(),
						  								 parseExpression(), "addtmp");
  case '-':
    result = Builder.CreateSub(parseExpression(),
						  								 parseExpression(), "subtmp");
  case '*':
    result = Builder.CreateMul(parseExpression(),
						  								 parseExpression(), "multmp");
  case '/':
    result = Builder.CreateSDiv(parseExpression(),
						  							    parseExpression(), "divtmp");
  case '%':
    result = Builder.CreateSRem(parseExpression(),
					  								 	  parseExpression(), "modtmp");
  default:
    printError(__LINE__, "Fatal error in compiler. Cannot reach here");
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parseNumber() {
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  int num = 0, count = 0;
  bool isNegative = false;
  char ch = getChar();

  if (ch == '-') {
    isNegative = true;
    ch = getnextChar();
  }
  while  ((ch >= '0') && (ch <= '9')) {
    num = (num * 10 * count++) + (0 + (ch - '0'));
    ch = getnextChar();
  }
  if (isNegative) {
    num = num * (-1);
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return ConstantInt::get(C, APInt(64, num));
}

Value* parseRelationalOperation() {
  Value* result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  if (accept('>')) {
    if (accept('=')) {
      //This is greater than equals
      result = Builder.CreateICmpSGE(parseExpression(),
                                     parseExpression(), "gethan");
    } else {
      //This is greater than
      result = Builder.CreateICmpSGT(parseExpression(),
                                     parseExpression(), "gthan");
    }
  } else if (accept('<')) {
    if (accept('=')) {
      //This is less than equals
      result = Builder.CreateICmpSLE(parseExpression(),
                                     parseExpression(), "lethan");
    } else {
      //This is less than
      result = Builder.CreateICmpSLT(parseExpression(),
                                     parseExpression(), "lthan");
    }
  } else if (accept('!') && accept('=')) {
    //This is not equal to
    result = Builder.CreateICmpNE(parseExpression(),
                                  parseExpression(), "ne");
  } else if (accept('=') && accept('=')) {
    //This is double equals
    result = Builder.CreateICmpEQ(parseExpression(),
                                  parseExpression(), "eq");
  } else {
    printError(__LINE__, "Invalid Relational Operator used");
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parseBoolExpression() {
  Value* result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  skipSpaces();

  char ch = getChar();

  if (accept('t') && accept('r') && accept('u') && accept('e')) {
    //Its a true condition
    result = ConstantInt::get(C, APInt(64, 1));
  } else if (accept('f') && accept('a') && accept('l')
      && accept('s') && accept('e')) {
    //Its a false condition
    result = ConstantInt::get(C, APInt(64, 0));
  } else if ((ch == '>') || (ch == '<') || (ch == '=') ||
             (ch == '!')) {
    result = parseRelationalOperation();
  } else if (ch == ('(')) {
    getnextChar();
    result = parseBoolExpression();
    if (accept(')') == false) {
      printError(__LINE__, "Missing ) Paranthesis in boolean exp");
    }
  } else {
    printError(__LINE__, "Boolean expression Missing");
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parseIf() {
  Value *result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  if (accept('i') && accept('f')) {
    result = Builder.CreateSelect(parseBoolExpression(),
                                  parseExpression(),
                                  parseExpression());
  } else {
    printError(__LINE__);
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

void skipSpaces() {
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  while (getChar() != EOF) {
    if (accept(' ')) {
      continue;
    } else if (accept('\n')) {
      gLineNo++;
      continue;
    }
    break;
  }

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
}

Value* parseExpression() {
  char errmsg[75];
  Value *result;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }

  skipSpaces();

  char ch = getChar();

  do{
    if (ch == '#') {
      parseComment();
    } else if (ch == 'a') {
      result = parseArgs();
      break;
    } else if (ch == '\n') {
      //Increment the line number, so that we can give a
      //meaningful error message
      gLineNo++;
    } else if (ch == ' ') {
      //Ignore White space
    } else if ((ch == '+') || (ch == '-') || (ch == '*') ||
               (ch == '/') || (ch == '%')) {
      getnextChar();
      result = parseArithmeticOperation(ch);
      break;
    } else if (ch == '-') {
      result = parseNumber();
      break;
    } else if ((ch >= '0') && (ch <= '9')) {
      result = parseNumber();
      break;
    } else if (ch == '(') {
      getnextChar();
      result = parseExpression();
      if (accept(')') == false) {
        printError(__LINE__, "Missing Matching paranthesis");
      }
      break;
    } else if (ch == 'i') {
      result = parseIf();
      break;
    } else if (ch == ')') {
      getnextChar();
      break;
    } else {
      printError(__LINE__);
    }
    ch = getChar();
  }while (ch != EOF);

  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

Value* parser() {
  Value *result = NULL;
  if (debug) {
    printf("Enter %s\r\n", __PRETTY_FUNCTION__);
  }
  char ch = getnextChar();
  while(ch != EOF) {
    if (ch == '#') {
      parseComment();
    } else {
      result = parseExpression();
      skipSpaces();
      if (getChar() == EOF) {
        break;
      } else {
        printError(__LINE__);
      }
    }
    ch = getChar();
  }
  printf("Parsed successfully\r\n");
  if (debug) {
    printf("Exit %s\r\n", __PRETTY_FUNCTION__);
  }
  return result;
}

static int compile() {
  M->setTargetTriple(llvm::sys::getProcessTriple());
  std::vector<Type *> SixInts(6, Type::getInt64Ty(C));
  FunctionType *FT = FunctionType::get(Type::getInt64Ty(C), SixInts, false);
  Function *F = Function::Create(FT, Function::ExternalLinkage, "f", &*M);
  BasicBlock *BB = BasicBlock::Create(C, "entry", F);
  Builder.SetInsertPoint(BB);

  // TODO: parse the source program
  // TODO: generate correct LLVM instead of just an empty function
  Value *RetVal = parser();

  //Value *RetVal = ConstantInt::get(C, APInt(64, 0));
  Builder.CreateRet(RetVal);
  assert(!verifyModule(*M, &outs()));
  M->dump();
  return 0;
}

int main(int argc, char **argv) {
  if (openFile(argc, argv) == true) {
    return compile();
  }
  return -1;
}
<|endoftext|>