<commit_before>// main.cpp (Oclgrind)
// Copyright (c) 2013-2014, James Price and Simon McIntosh-Smith,
// University of Bristol. All rights reserved.
//
// This program is provided under a three-clause BSD license. For full
// license terms please see the LICENSE file distributed with this
// source code.

#include <fstream>
#include <string>

#include "spirsim/Device.h"
#include "spirsim/Kernel.h"
#include "spirsim/Memory.h"
#include "spirsim/Program.h"

using namespace spirsim;
using namespace std;

static bool outputGlobalMemory = false;
static const char *simfile = NULL;

static size_t ndrange[3];
static size_t wgsize[3];
static Device *device = NULL;
static Program *program = NULL;
static Kernel *kernel = NULL;

static bool init(istream& input);
static bool parseArguments(int argc, char *argv[]);
static void printUsage();

int main(int argc, char *argv[])
{
  // Parse arguments
  if (!parseArguments(argc, argv))
  {
    return 1;
  }

  // Attempt to open simulator file
  ifstream input;
  input.open(simfile);
  if (input.fail())
  {
    cerr << "Unable to open simulator file." << endl;
    return 1;
  }

  // Initialise simulator
  device = new Device();
  bool ret = init(input);
  input.close();
  if (!ret)
  {
    return 1;
  }

  // Run kernel
  size_t offset[3] = {0,0,0};
  device->run(*kernel, 3, offset, ndrange, wgsize);
  if (outputGlobalMemory)
  {
    cout << "Global Memory:" << endl;
    device->getGlobalMemory()->dump();
  }

  delete device;
  delete kernel;
  delete program;
}

bool init(istream& input)
{
  string progFileName;
  string kernelName;

  // Read simulation parameters
  input >> progFileName
        >> kernelName
        >> ndrange[0] >> ndrange[1] >> ndrange[2]
        >> wgsize[0] >> wgsize[1] >> wgsize[2];

  // Ensure work-group size exactly divides NDRange
  if (ndrange[0] % wgsize[0] ||
      ndrange[1] % wgsize[1] ||
      ndrange[2] % wgsize[2])
  {
    cerr << "Work group size must divide NDRange exactly." << endl;
    return false;
  }

  // Open program file
  ifstream progFile;
  progFile.open(progFileName.c_str(), ios_base::in | ios_base::binary);
  if (!progFile.good())
  {
    cerr << "Unable to open " << progFileName << endl;
    return false;
  }

  // Check for LLVM bitcode magic numbers
  char magic[2] = {0,0};
  progFile.read(magic, 2);
  if (magic[0] == 0x42 && magic[1] == 0x43)
  {
    // Load bitcode
    progFile.close();
    program = Program::createFromBitcodeFile(progFileName);
    if (!program)
    {
      cerr << "Failed to load bitcode from " << progFileName << endl;
      return false;
    }
  }
  else
  {
    // Get size of file
    progFile.seekg(0, ios_base::end);
    size_t sz = progFile.tellg();
    progFile.seekg(0, ios_base::beg);

    // Load source
    char *data = new char[sz + 1];
    progFile.read(data, sz+1);
    progFile.close();
    data[sz] = '\0';
    program = new Program(data);
    delete[] data;

    // Build program
    if (!program->build(""))
    {
      cerr << "Build failure:" << endl << program->getBuildLog() << endl;
      return false;
    }
  }

  // Get kernel
  kernel = program->createKernel(kernelName);
  if (!kernel)
  {
    cerr << "Failed to create kernel " << kernelName << endl;
    return false;
  }

  // Clear global memory
  Memory *globalMemory = device->getGlobalMemory();
  globalMemory->clear();

  // Set kernel arguments
  for (int idx = 0; idx < kernel->getNumArguments(); idx++)
  {
    char type;
    size_t size;
    size_t address;
    int i;
    int byte;
    TypedValue value;

    input >> type >> dec >> size;
    if (input.fail())
    {
      cerr << "Error reading kernel arguments." << endl;
      return false;
    }

    switch (type)
    {
    case 'b':
      // Allocate buffer
      address = globalMemory->allocateBuffer(size);
      if (!address)
      {
        cerr << "Failed to allocate buffer" << endl;
        return false;
      }

      // Initialise buffer
      for (i = 0; i < size; i++)
      {
        input >> hex >> byte;
        globalMemory->store((unsigned char*)&byte, address + i);
      }

      // Set argument value
      value.size = sizeof(size_t);
      value.num = 1;
      value.data = new unsigned char[value.size];
      *((size_t*)value.data) = address;

      break;
    case 'l':
      // Allocate local memory argument
      value.size = size;
      value.num = 1;
      value.data = NULL;

      break;
    case 's':
      // Create scalar argument
      value.size = size;
      value.num = 1;
      value.data = new unsigned char[value.size];
      for (i = 0; i < size; i++)
      {
        input >> hex >> byte;
        value.data[i] = (unsigned char)byte;
      }

      break;
    default:
      cerr << "Unrecognised argument type '" << type << "'" << endl;
      return false;
    }

    kernel->setArgument(idx, value);
    if (value.data)
    {
      delete[] value.data;
    }
  }

  // Make sure there is no more input
  std::string next;
  input >> next;
  if (input.good() || !input.eof())
  {
    cerr << "Unexpected token '" << next << "' (expected EOF)" << endl;
    return false;
  }

  return true;
}

static bool parseArguments(int argc, char *argv[])
{
  for (int i = 1; i < argc; i++)
  {
    if (argv[i][0] == '-')
    {
      char *opt = argv[i] + 1;
      while (*opt != '\0')
      {
        switch (*opt)
        {
        case 'g':
          outputGlobalMemory = true;
          break;
        default:
          cerr << "Unrecognised option '" << argv[i] << "'" << endl;
          return false;
        }
        opt++;
      }
    }
    else
    {
      if (simfile == NULL)
      {
        simfile = argv[i];
      }
      else
      {
        cerr << "Unexpected positional argument '" << argv[i] << "'" << endl;
        return false;
      }
    }
  }

  if (simfile == NULL)
  {
    printUsage();
    return false;
  }

  return true;
}

static void printUsage()
{
  cout << "Usage: oclgrind-kernel [-g] simfile" << endl;
}
<commit_msg>Added arguments to oclgrind-kernel to match oclgrind.<commit_after>// main.cpp (Oclgrind)
// Copyright (c) 2013-2014, James Price and Simon McIntosh-Smith,
// University of Bristol. All rights reserved.
//
// This program is provided under a three-clause BSD license. For full
// license terms please see the LICENSE file distributed with this
// source code.

#include <fstream>
#include <string>

#include "spirsim/Device.h"
#include "spirsim/Kernel.h"
#include "spirsim/Memory.h"
#include "spirsim/Program.h"

using namespace spirsim;
using namespace std;

static bool outputGlobalMemory = false;
static const char *simfile = NULL;

static size_t ndrange[3];
static size_t wgsize[3];
static Device *device = NULL;
static Program *program = NULL;
static Kernel *kernel = NULL;

static bool init(istream& input);
static bool parseArguments(int argc, char *argv[]);
static void printUsage();

int main(int argc, char *argv[])
{
  // Parse arguments
  if (!parseArguments(argc, argv))
  {
    return 1;
  }

  // Attempt to open simulator file
  ifstream input;
  input.open(simfile);
  if (input.fail())
  {
    cerr << "Unable to open simulator file." << endl;
    return 1;
  }

  // Initialise simulator
  device = new Device();
  bool ret = init(input);
  input.close();
  if (!ret)
  {
    return 1;
  }

  // Run kernel
  size_t offset[3] = {0,0,0};
  device->run(*kernel, 3, offset, ndrange, wgsize);
  if (outputGlobalMemory)
  {
    cout << "Global Memory:" << endl;
    device->getGlobalMemory()->dump();
  }

  delete device;
  delete kernel;
  delete program;
}

bool init(istream& input)
{
  string progFileName;
  string kernelName;

  // Read simulation parameters
  input >> progFileName
        >> kernelName
        >> ndrange[0] >> ndrange[1] >> ndrange[2]
        >> wgsize[0] >> wgsize[1] >> wgsize[2];

  // Ensure work-group size exactly divides NDRange
  if (ndrange[0] % wgsize[0] ||
      ndrange[1] % wgsize[1] ||
      ndrange[2] % wgsize[2])
  {
    cerr << "Work group size must divide NDRange exactly." << endl;
    return false;
  }

  // Open program file
  ifstream progFile;
  progFile.open(progFileName.c_str(), ios_base::in | ios_base::binary);
  if (!progFile.good())
  {
    cerr << "Unable to open " << progFileName << endl;
    return false;
  }

  // Check for LLVM bitcode magic numbers
  char magic[2] = {0,0};
  progFile.read(magic, 2);
  if (magic[0] == 0x42 && magic[1] == 0x43)
  {
    // Load bitcode
    progFile.close();
    program = Program::createFromBitcodeFile(progFileName);
    if (!program)
    {
      cerr << "Failed to load bitcode from " << progFileName << endl;
      return false;
    }
  }
  else
  {
    // Get size of file
    progFile.seekg(0, ios_base::end);
    size_t sz = progFile.tellg();
    progFile.seekg(0, ios_base::beg);

    // Load source
    char *data = new char[sz + 1];
    progFile.read(data, sz+1);
    progFile.close();
    data[sz] = '\0';
    program = new Program(data);
    delete[] data;

    // Build program
    if (!program->build(""))
    {
      cerr << "Build failure:" << endl << program->getBuildLog() << endl;
      return false;
    }
  }

  // Get kernel
  kernel = program->createKernel(kernelName);
  if (!kernel)
  {
    cerr << "Failed to create kernel " << kernelName << endl;
    return false;
  }

  // Clear global memory
  Memory *globalMemory = device->getGlobalMemory();
  globalMemory->clear();

  // Set kernel arguments
  for (int idx = 0; idx < kernel->getNumArguments(); idx++)
  {
    char type;
    size_t size;
    size_t address;
    int i;
    int byte;
    TypedValue value;

    input >> type >> dec >> size;
    if (input.fail())
    {
      cerr << "Error reading kernel arguments." << endl;
      return false;
    }

    switch (type)
    {
    case 'b':
      // Allocate buffer
      address = globalMemory->allocateBuffer(size);
      if (!address)
      {
        cerr << "Failed to allocate buffer" << endl;
        return false;
      }

      // Initialise buffer
      for (i = 0; i < size; i++)
      {
        input >> hex >> byte;
        globalMemory->store((unsigned char*)&byte, address + i);
      }

      // Set argument value
      value.size = sizeof(size_t);
      value.num = 1;
      value.data = new unsigned char[value.size];
      *((size_t*)value.data) = address;

      break;
    case 'l':
      // Allocate local memory argument
      value.size = size;
      value.num = 1;
      value.data = NULL;

      break;
    case 's':
      // Create scalar argument
      value.size = size;
      value.num = 1;
      value.data = new unsigned char[value.size];
      for (i = 0; i < size; i++)
      {
        input >> hex >> byte;
        value.data[i] = (unsigned char)byte;
      }

      break;
    default:
      cerr << "Unrecognised argument type '" << type << "'" << endl;
      return false;
    }

    kernel->setArgument(idx, value);
    if (value.data)
    {
      delete[] value.data;
    }
  }

  // Make sure there is no more input
  std::string next;
  input >> next;
  if (input.good() || !input.eof())
  {
    cerr << "Unexpected token '" << next << "' (expected EOF)" << endl;
    return false;
  }

  return true;
}

static bool parseArguments(int argc, char *argv[])
{
  for (int i = 1; i < argc; i++)
  {
    if (!strcmp(argv[i], "--data-races"))
    {
#if defined(_WIN32) && !defined(__MINGW32__)
      _putenv("OCLGRIND_DATA_RACES=1");
#else
      setenv("OCLGRIND_DATA_RACES", "1", 1);
#endif
    }
    else if (!strcmp(argv[i], "--dump-spir"))
    {
#if defined(_WIN32) && !defined(__MINGW32__)
      _putenv("OCLGRIND_DUMP_SPIR=1");
#else
      setenv("OCLGRIND_DUMP_SPIR", "1", 1);
#endif
    }
    else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--global-mem"))
    {
      outputGlobalMemory = true;
    }
    else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
    {
      printUsage();
      exit(0);
    }
    else if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--interactive"))
    {
#if defined(_WIN32) && !defined(__MINGW32__)
      _putenv("OCLGRIND_INTERACTIVE=1");
#else
      setenv("OCLGRIND_INTERACTIVE", "1", 1);
#endif
    }
    else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version"))
    {
      cout << endl;
      cout << "Oclgrind " PACKAGE_VERSION << endl;
      cout << endl;
      cout << "Copyright (c) 2013-2014" << endl;
      cout << "James Price and Simon McIntosh-Smith, University of Bristol"
           << endl;
      cout << "https://github.com/jrprice/Oclgrind" << endl;
      cout << endl;
      exit(0);
    }
    else if (argv[i][0] == '-')
    {
      cerr << "Unrecognised option '" << argv[i] << "'" << endl;
      return false;
    }
    else
    {
      if (simfile == NULL)
      {
        simfile = argv[i];
      }
      else
      {
        cerr << "Unexpected positional argument '" << argv[i] << "'" << endl;
        return false;
      }
    }
  }

  if (simfile == NULL)
  {
    printUsage();
    return false;
  }

  return true;
}

static void printUsage()
{
  cout << "Usage: oclgrind-kernel [OPTIONS] simfile" << endl;
  cout << "       oclgrind-kernel [--help | --version]" << endl;
  cout << endl;
  cout << "Options:" << endl;
  cout << "     --data-races    Enable data-race detection" << endl;
  cout << "     --dump-spir     Dump SPIR to /tmp/oclgrind_*.{ll,bc}" << endl;
  cout << "  -g --global-mem    Output global memory at exit" << endl;
  cout << "  -h --help          Display usage information" << endl;
  cout << "  -i --interactive   Enable interactive mode" << endl;
  cout << "  -v --version       Display version information" << endl;
  cout << endl;
  cout << "For more information, please visit the Oclgrind wiki page:" << endl;
  cout << "-> https://github.com/jrprice/Oclgrind/wiki" << endl;
  cout << endl;
}
<|endoftext|>


<commit_before>/*!
 * \file SickLMSBufferMonitor.cc
 * \brief Implements a class for monitoring the receive
 *        buffer when interfacing w/ a Sick LMS LIDAR.
 *
 * Code by Jason C. Derenick and Thomas H. Miller.
 * Contact derenick(at)lehigh(dot)edu
 *
 * The Sick LIDAR Matlab/C++ Toolbox
 * Copyright (c) 2008, Jason C. Derenick and Thomas H. Miller
 * All rights reserved.
 *
 * This software is released under a BSD Open-Source License.
 * See http://sicktoolbox.sourceforge.net
 */

/* Auto-generated header */
#include "SickConfig.hh"

/* Implementation dependencies */
#include <iostream>
#include <termios.h>

#include "SickLMS.hh"
#include "SickLMSBufferMonitor.hh"
#include "SickLMSMessage.hh"
#include "SickException.hh"
#include "SickLMSUtility.hh"

/* Associate the namespace */
namespace SickToolbox {

  /**
   * \brief A standard constructor
   */
  SickLMSBufferMonitor::SickLMSBufferMonitor( ) : SickBufferMonitor<SickLMSBufferMonitor,SickLMSMessage>(this) { }

  /**
   * \brief Acquires the next message from the SickLMS byte stream
   * \param &sick_message The returned message object
   */
  void SickLMSBufferMonitor::GetNextMessageFromDataStream( SickLMSMessage &sick_message ) throw( SickIOException ) {

    uint8_t search_buffer[2] = {0};
    uint8_t payload_length_buffer[2] = {0};
    uint8_t payload_buffer[SickLMSMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
    uint8_t checksum_buffer[2] = {0};
    uint16_t payload_length, checksum;

    try {

      /* Drain the I/O buffers! */
      if (tcdrain(_sick_fd) != 0) {
     	throw SickIOException("SickLMS::_getNextMessageFromDataStream: tcdrain failed!");
      }

      /* Read until we get a valid message header */
      unsigned int bytes_searched = 0;
      while(search_buffer[0] != 0x02 || search_buffer[1] != DEFAULT_SICK_LMS_HOST_ADDRESS) {

 	/* Slide the search window */
 	search_buffer[0] = search_buffer[1];

 	/* Attempt to read in another byte */
 	_readBytes(&search_buffer[1],1,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

	/* Header should be no more than max message length + header length bytes away */
	if (bytes_searched > SickLMSMessage::MESSAGE_MAX_LENGTH + SickLMSMessage::MESSAGE_HEADER_LENGTH) {
	  throw SickTimeoutException("SickLMSBufferMonitor::GetNextMessageFromDataStream: header timeout!");
	}

	/* Increment the number of bytes searched */
	bytes_searched++;

      }

      /* Read until we receive the payload length or we timeout */
      _readBytes(payload_length_buffer,2,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

      /* Extract the payload length */
      memcpy(&payload_length,payload_length_buffer,2);
      payload_length = sick_lms_to_host_byte_order(payload_length);

      /* Make sure the payload length is legitimate, otherwise disregard */
      if (payload_length <= SickLMSMessage::MESSAGE_MAX_LENGTH) {

	/* Read until we receive the payload or we timeout */
	_readBytes(payload_buffer,payload_length,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

	/* Read until we receive the checksum or we timeout */
	_readBytes(checksum_buffer,2,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

	/* Copy into uint16_t so it can be used */
	memcpy(&checksum,checksum_buffer,2);
	checksum = sick_lms_to_host_byte_order(checksum);

	/* Build a frame and compute the crc */
	sick_message.BuildMessage(DEFAULT_SICK_LMS_HOST_ADDRESS,payload_buffer,payload_length);

	/* See if the checksums match */
	if(sick_message.GetChecksum() != checksum) {
	  throw SickBadChecksumException("SickLMS::_getNextMessageFromDataStream: CRC16 failed!");
	}

      }

    }

    catch(SickTimeoutException &sick_timeout_exception) { /* This is ok! */ }

    /* Catch a bad checksum! */
    catch(SickBadChecksumException &sick_checksum_exception) {
      std::cerr << sick_checksum_exception.what() << std::endl;
    }

    /* Catch any serious IO exceptions */
    catch(SickIOException &sick_io_exception) {
      std::cerr << sick_io_exception.what() << std::endl;
      throw;
    }

    /* A sanity check */
    catch (...) {
      std::cerr << "SickLMSBufferMonitor::_getNextMessageFromByteStream: Unknown exception!" << std::endl;
      throw;
    }

  }

  /**
   * \brief A standard destructor
   */
  SickLMSBufferMonitor::~SickLMSBufferMonitor( ) { }

} /* namespace SickToolbox */
<commit_msg>Monitor now clears msg container on bad checksum<commit_after>/*!
 * \file SickLMSBufferMonitor.cc
 * \brief Implements a class for monitoring the receive
 *        buffer when interfacing w/ a Sick LMS LIDAR.
 *
 * Code by Jason C. Derenick and Thomas H. Miller.
 * Contact derenick(at)lehigh(dot)edu
 *
 * The Sick LIDAR Matlab/C++ Toolbox
 * Copyright (c) 2008, Jason C. Derenick and Thomas H. Miller
 * All rights reserved.
 *
 * This software is released under a BSD Open-Source License.
 * See http://sicktoolbox.sourceforge.net
 */

/* Auto-generated header */
#include "SickConfig.hh"

/* Implementation dependencies */
#include <iostream>
#include <termios.h>

#include "SickLMS.hh"
#include "SickLMSBufferMonitor.hh"
#include "SickLMSMessage.hh"
#include "SickException.hh"
#include "SickLMSUtility.hh"

/* Associate the namespace */
namespace SickToolbox {

  /**
   * \brief A standard constructor
   */
  SickLMSBufferMonitor::SickLMSBufferMonitor( ) : SickBufferMonitor<SickLMSBufferMonitor,SickLMSMessage>(this) { }

  /**
   * \brief Acquires the next message from the SickLMS byte stream
   * \param &sick_message The returned message object
   */
  void SickLMSBufferMonitor::GetNextMessageFromDataStream( SickLMSMessage &sick_message ) throw( SickIOException ) {

    uint8_t search_buffer[2] = {0};
    uint8_t payload_length_buffer[2] = {0};
    uint8_t payload_buffer[SickLMSMessage::MESSAGE_PAYLOAD_MAX_LENGTH] = {0};
    uint8_t checksum_buffer[2] = {0};
    uint16_t payload_length, checksum;

    try {

      /* Drain the I/O buffers! */
      if (tcdrain(_sick_fd) != 0) {
     	throw SickIOException("SickLMS::_getNextMessageFromDataStream: tcdrain failed!");
      }

      /* Read until we get a valid message header */
      unsigned int bytes_searched = 0;
      while(search_buffer[0] != 0x02 || search_buffer[1] != DEFAULT_SICK_LMS_HOST_ADDRESS) {

 	/* Slide the search window */
 	search_buffer[0] = search_buffer[1];

 	/* Attempt to read in another byte */
 	_readBytes(&search_buffer[1],1,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

	/* Header should be no more than max message length + header length bytes away */
	if (bytes_searched > SickLMSMessage::MESSAGE_MAX_LENGTH + SickLMSMessage::MESSAGE_HEADER_LENGTH) {
	  throw SickTimeoutException("SickLMSBufferMonitor::GetNextMessageFromDataStream: header timeout!");
	}

	/* Increment the number of bytes searched */
	bytes_searched++;

      }

      /* Read until we receive the payload length or we timeout */
      _readBytes(payload_length_buffer,2,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

      /* Extract the payload length */
      memcpy(&payload_length,payload_length_buffer,2);
      payload_length = sick_lms_to_host_byte_order(payload_length);

      /* Make sure the payload length is legitimate, otherwise disregard */
      if (payload_length <= SickLMSMessage::MESSAGE_MAX_LENGTH) {

	/* Read until we receive the payload or we timeout */
	_readBytes(payload_buffer,payload_length,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

	/* Read until we receive the checksum or we timeout */
	_readBytes(checksum_buffer,2,DEFAULT_SICK_LMS_SICK_BYTE_TIMEOUT);

	/* Copy into uint16_t so it can be used */
	memcpy(&checksum,checksum_buffer,2);
	checksum = sick_lms_to_host_byte_order(checksum);

	/* Build a frame and compute the crc */
	sick_message.BuildMessage(DEFAULT_SICK_LMS_HOST_ADDRESS,payload_buffer,payload_length);

	/* See if the checksums match */
	if(sick_message.GetChecksum() != checksum) {
	  throw SickBadChecksumException("SickLMS::_getNextMessageFromDataStream: CRC16 failed!");
	}

      }

    }

    catch(SickTimeoutException &sick_timeout_exception) { /* This is ok! */ }

    /* Catch a bad checksum! */
    catch(SickBadChecksumException &sick_checksum_exception) {
      sick_message.Clear(); // Clear the message container
      std::cerr << sick_checksum_exception.what() << std::endl;
    }

    /* Catch any serious IO exceptions */
    catch(SickIOException &sick_io_exception) {
      std::cerr << sick_io_exception.what() << std::endl;
      throw;
    }

    /* A sanity check */
    catch (...) {
      std::cerr << "SickLMSBufferMonitor::_getNextMessageFromByteStream: Unknown exception!" << std::endl;
      throw;
    }

  }

  /**
   * \brief A standard destructor
   */
  SickLMSBufferMonitor::~SickLMSBufferMonitor( ) { }

} /* namespace SickToolbox */
<|endoftext|>


<commit_before><commit_msg>CID#1103763 uninitialized member<commit_after><|endoftext|>


<commit_before>/*****************************************************************************************
 *                                                                                *
 * GHOUL                                                                                *
 * General Helpful Open Utility Library                                                  *
 *                                                                                *
 * Copyright (c) 2012 Alexander Bock                                                     *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#include <ghoul/opengl/texturereader.h>

#include <ghoul/opengl/texture.h>
#include <ghoul/logging/logmanager.h>
#include "glm/glm.hpp"

#include <IL/il.h>

namespace ghoul {
namespace opengl {

Texture* loadTexture(const std::string& filename, bool useCompression) {
    std::string _loggerCat = "loadTexture";

    ilInit();
    //ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
    //ilEnable(IL_ORIGIN_SET);

    ILboolean loadSuccess = ilLoadImage(filename.c_str());
    if (!loadSuccess) {
        ILenum error = ilGetError();
        if (error == IL_COULD_NOT_OPEN_FILE)
            LERROR("Could not open image file '" << filename <<
                        "'. File did not exist.");
        else if (error == IL_ILLEGAL_OPERATION)
            LERROR("Could not open image file '" << filename <<
                        "'. Illegal operation.");
        else if (error == IL_INVALID_EXTENSION)
            LERROR("Could not open image file '" << filename <<
                        "'. The file could not be loaded based on extension or header.");
        else if (error == IL_INVALID_PARAM)
            LERROR("Could not open image file '" << filename <<
                        "'. FileName was not valid. It was most likely NULL.");
        else if (error == IL_OUT_OF_MEMORY)
            LERROR("Could not allocate enough memory for '" << filename << "'.");
        else if (error == IL_NO_ERROR)
            LERROR("Could not open image file '" << filename <<
                        "'. No error reported.");
        else if (error == IL_UNKNOWN_ERROR)
            LERROR("Could not open image file '" << filename <<
                        "'. Unknown reported.");
        else
            LERROR("Could not open/read image file '" << filename <<
                        "'. Error message: " << error);
        return nullptr;
    }
    ILint imageFormat = ilGetInteger(IL_IMAGE_FORMAT);
    ILint imageType = ilGetInteger(IL_IMAGE_TYPE);
    ILint imageByte = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
    ILint width = ilGetInteger(IL_IMAGE_WIDTH);
    ILint height = ilGetInteger(IL_IMAGE_HEIGHT);
    ILint depth = ilGetInteger(IL_IMAGE_DEPTH);

    // Copy data from common data store to own address space
    ILubyte* data = new ILubyte[width * height * imageByte];
    ilCopyPixels(0, 0, 0, width, height, 1, imageFormat, IL_UNSIGNED_BYTE, data);

    glm::size3_t size(width, height, depth);

    Texture::Format format;
    switch (imageFormat) {
        case IL_RGB:
            format = Texture::Format::RGB;
            break;
        case IL_RGBA:
            format = Texture::Format::RGBA;
            break;
        case IL_BGR:
            format = Texture::Format::BGR;
            break;
        case IL_BGRA:
            format = Texture::Format::BGRA;
            break;
        default:
            LERROR("Could not read image file '" << filename << "' of format: '" <<
                        imageFormat << "'");
            return nullptr;
    }

    GLenum type;
    switch (imageType) {
        case IL_UNSIGNED_BYTE:
            type = GL_UNSIGNED_BYTE;
            break;
        case IL_BYTE:
            type = GL_BYTE;
            break;
        case IL_UNSIGNED_SHORT:
            type = GL_UNSIGNED_SHORT;
            break;
        case IL_SHORT:
            type = GL_SHORT;
            break;
        case IL_UNSIGNED_INT:
            type = GL_UNSIGNED_INT;
            break;
        case IL_INT:
            type = GL_INT;
            break;
        case IL_FLOAT:
            type = GL_FLOAT;
            break;
        default:
            LERROR("Could not read image file '" << filename <<
                        "' of data type: '" << imageType << "'");
            return nullptr;
    }

    Texture* result;
    if (useCompression) {
        switch (format) {
            case Texture::Format::RGB:
                result = new Texture(data, size, format,
                                     GL_COMPRESSED_RGB_S3TC_DXT1_EXT, type);
                break;
            case Texture::Format::RGBA:
                result = new Texture(data, size, format,
                                     GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, type);
                break;
            default:
                LERROR("Could not assign compressed format for: '" <<
                    GLint(format) << "'. Using no compression instead");
                result = new Texture(data, size, format, static_cast<int>(format), type);
                break;
        }
    }
    else
        result = new Texture(data, size, format, static_cast<int>(format), type);

    return result;
}

} // namespace opengl
} // namespace ghoul
<commit_msg>replaced if-else construct in TextureReader with 'iluGetError' string message<commit_after>/*****************************************************************************************
 *                                                                                *
 * GHOUL                                                                                *
 * General Helpful Open Utility Library                                                  *
 *                                                                                *
 * Copyright (c) 2012 Alexander Bock                                                     *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#include <ghoul/opengl/texturereader.h>

#include <ghoul/opengl/texture.h>
#include <ghoul/logging/logmanager.h>
#include "glm/glm.hpp"

#include <IL/il.h>
#include <IL/ilu.h>

namespace ghoul {
namespace opengl {

Texture* loadTexture(const std::string& filename, bool useCompression) {
    std::string _loggerCat = "loadTexture";

    ilInit();
    //ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
    //ilEnable(IL_ORIGIN_SET);

    ILboolean loadSuccess = ilLoadImage(filename.c_str());
    if (!loadSuccess) {
        ILenum error = ilGetError();
        LERROR("Error while loading image '" << filename << "': " <<
                    iluErrorString(error));
        return nullptr;
    }
    ILint imageFormat = ilGetInteger(IL_IMAGE_FORMAT);
    ILint imageType = ilGetInteger(IL_IMAGE_TYPE);
    ILint imageByte = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
    ILint width = ilGetInteger(IL_IMAGE_WIDTH);
    ILint height = ilGetInteger(IL_IMAGE_HEIGHT);
    ILint depth = ilGetInteger(IL_IMAGE_DEPTH);

    // Copy data from common data store to own address space
    ILubyte* data = new ILubyte[width * height * imageByte];
    ilCopyPixels(0, 0, 0, width, height, 1, imageFormat, IL_UNSIGNED_BYTE, data);

    glm::size3_t size(width, height, depth);

    Texture::Format format;
    switch (imageFormat) {
        case IL_RGB:
            format = Texture::Format::RGB;
            break;
        case IL_RGBA:
            format = Texture::Format::RGBA;
            break;
        case IL_BGR:
            format = Texture::Format::BGR;
            break;
        case IL_BGRA:
            format = Texture::Format::BGRA;
            break;
        default:
            LERROR("Could not read image file '" << filename << "' of format: '" <<
                        imageFormat << "'");
            return nullptr;
    }

    GLenum type;
    switch (imageType) {
        case IL_UNSIGNED_BYTE:
            type = GL_UNSIGNED_BYTE;
            break;
        case IL_BYTE:
            type = GL_BYTE;
            break;
        case IL_UNSIGNED_SHORT:
            type = GL_UNSIGNED_SHORT;
            break;
        case IL_SHORT:
            type = GL_SHORT;
            break;
        case IL_UNSIGNED_INT:
            type = GL_UNSIGNED_INT;
            break;
        case IL_INT:
            type = GL_INT;
            break;
        case IL_FLOAT:
            type = GL_FLOAT;
            break;
        default:
            LERROR("Could not read image file '" << filename <<
                        "' of data type: '" << imageType << "'");
            return nullptr;
    }

    Texture* result;
    if (useCompression) {
        switch (format) {
            case Texture::Format::RGB:
                result = new Texture(data, size, format,
                                     GL_COMPRESSED_RGB_S3TC_DXT1_EXT, type);
                break;
            case Texture::Format::RGBA:
                result = new Texture(data, size, format,
                                     GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, type);
                break;
            default:
                LERROR("Could not assign compressed format for: '" <<
                    GLint(format) << "'. Using no compression instead");
                result = new Texture(data, size, format, static_cast<int>(format), type);
                break;
        }
    }
    else
        result = new Texture(data, size, format, static_cast<int>(format), type);

    return result;
}

} // namespace opengl
} // namespace ghoul
<|endoftext|>


<commit_before>/*
 * Copyright 2009 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBitmapProcState_opts_SSE2.h"
#include "SkBitmapProcState_opts_SSSE3.h"
#include "SkBitmapFilter_opts_SSE2.h"
#include "SkBlitMask.h"
#include "SkBlitRow.h"
#include "SkBlitRect_opts_SSE2.h"
#include "SkBlitRow_opts_SSE2.h"
#include "SkUtils_opts_SSE2.h"
#include "SkUtils.h"

#include "SkRTConf.h"

#if defined(_MSC_VER) && defined(_WIN64)
#include <intrin.h>
#endif

/* This file must *not* be compiled with -msse or -msse2, otherwise
   gcc may generate sse2 even for scalar ops (and thus give an invalid
   instruction on Pentium3 on the code below).  Only files named *_SSE2.cpp
   in this directory should be compiled with -msse2. */

#ifdef _MSC_VER
static inline void getcpuid(int info_type, int info[4]) {
#if defined(_WIN64)
    __cpuid(info, info_type);
#else
    __asm {
        mov    eax, [info_type]
        cpuid
        mov    edi, [info]
        mov    [edi], eax
        mov    [edi+4], ebx
        mov    [edi+8], ecx
        mov    [edi+12], edx
    }
#endif
}
#else
#if defined(__x86_64__)
static inline void getcpuid(int info_type, int info[4]) {
    asm volatile (
        "cpuid \n\t"
        : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3])
        : "a"(info_type)
    );
}
#else
static inline void getcpuid(int info_type, int info[4]) {
    // We save and restore ebx, so this code can be compatible with -fPIC
    asm volatile (
        "pushl %%ebx      \n\t"
        "cpuid            \n\t"
        "movl %%ebx, %1   \n\t"
        "popl %%ebx       \n\t"
        : "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
        : "a"(info_type)
    );
}
#endif
#endif

#if defined(__x86_64__) || defined(_WIN64) || SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
/* All x86_64 machines have SSE2, or we know it's supported at compile time,  so don't even bother checking. */
static inline bool hasSSE2() {
    return true;
}
#else

static inline bool hasSSE2() {
    int cpu_info[4] = { 0 };
    getcpuid(1, cpu_info);
    return (cpu_info[3] & (1<<26)) != 0;
}
#endif

#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
/* If we know SSSE3 is supported at compile time, don't even bother checking. */
static inline bool hasSSSE3() {
    return true;
}
#else

static inline bool hasSSSE3() {
    int cpu_info[4] = { 0 };
    getcpuid(1, cpu_info);
    return (cpu_info[2] & 0x200) != 0;
}
#endif

static bool cachedHasSSE2() {
    static bool gHasSSE2 = hasSSE2();
    return gHasSSE2;
}

static bool cachedHasSSSE3() {
    static bool gHasSSSE3 = hasSSSE3();
    return gHasSSSE3;
}

SK_CONF_DECLARE( bool, c_hqfilter_sse, "bitmap.filter.highQualitySSE", false, "Use SSE optimized version of high quality image filters");

void SkBitmapProcState::platformConvolutionProcs() {
    if (cachedHasSSE2()) {
        fConvolutionProcs->fExtraHorizontalReads = 3;
        fConvolutionProcs->fConvolveVertically = &convolveVertically_SSE2;
        fConvolutionProcs->fConvolve4RowsHorizontally = &convolve4RowsHorizontally_SSE2;
        fConvolutionProcs->fConvolveHorizontally = &convolveHorizontally_SSE2;
        fConvolutionProcs->fApplySIMDPadding = &applySIMDPadding_SSE2;
    }
}

void SkBitmapProcState::platformProcs() {
    if (cachedHasSSSE3()) {
        if (fSampleProc32 == S32_opaque_D32_filter_DX) {
            fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3;
        } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
            fSampleProc32 = S32_alpha_D32_filter_DX_SSSE3;
        }

        if (fSampleProc32 == S32_opaque_D32_filter_DXDY) {
            fSampleProc32 = S32_opaque_D32_filter_DXDY_SSSE3;
        } else if (fSampleProc32 == S32_alpha_D32_filter_DXDY) {
            fSampleProc32 = S32_alpha_D32_filter_DXDY_SSSE3;
        }
    } else if (cachedHasSSE2()) {
        if (fSampleProc32 == S32_opaque_D32_filter_DX) {
            fSampleProc32 = S32_opaque_D32_filter_DX_SSE2;
        } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
            fSampleProc32 = S32_alpha_D32_filter_DX_SSE2;
        }

        if (fSampleProc16 == S32_D16_filter_DX) {
            fSampleProc16 = S32_D16_filter_DX_SSE2;
        }
    }

    if (cachedHasSSSE3() || cachedHasSSE2()) {
        if (fMatrixProc == ClampX_ClampY_filter_scale) {
            fMatrixProc = ClampX_ClampY_filter_scale_SSE2;
        } else if (fMatrixProc == ClampX_ClampY_nofilter_scale) {
            fMatrixProc = ClampX_ClampY_nofilter_scale_SSE2;
        }

        if (fMatrixProc == ClampX_ClampY_filter_affine) {
            fMatrixProc = ClampX_ClampY_filter_affine_SSE2;
        } else if (fMatrixProc == ClampX_ClampY_nofilter_affine) {
            fMatrixProc = ClampX_ClampY_nofilter_affine_SSE2;
        }
        if (c_hqfilter_sse) {
            if (fShaderProc32 == highQualityFilter) {
                fShaderProc32 = highQualityFilter_SSE2;
            }
        }
    }
}

static SkBlitRow::Proc32 platform_32_procs[] = {
    NULL,                               // S32_Opaque,
    S32_Blend_BlitRow32_SSE2,           // S32_Blend,
    S32A_Opaque_BlitRow32_SSE2,         // S32A_Opaque
    S32A_Blend_BlitRow32_SSE2,          // S32A_Blend,
};

SkBlitRow::Proc SkBlitRow::PlatformProcs565(unsigned flags) {
    return NULL;
}

SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
    if (cachedHasSSE2()) {
        return Color32_SSE2;
    } else {
        return NULL;
    }
}

SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
    if (cachedHasSSE2()) {
        return platform_32_procs[flags];
    } else {
        return NULL;
    }
}

SkBlitMask::ColorProc SkBlitMask::PlatformColorProcs(SkBitmap::Config dstConfig,
                                                     SkMask::Format maskFormat,
                                                     SkColor color) {
    if (SkMask::kA8_Format != maskFormat) {
        return NULL;
    }

    ColorProc proc = NULL;
    if (cachedHasSSE2()) {
        switch (dstConfig) {
            case SkBitmap::kARGB_8888_Config:
                // The SSE2 version is not (yet) faster for black, so we check
                // for that.
                if (SK_ColorBLACK != color) {
                    proc = SkARGB32_A8_BlitMask_SSE2;
                }
                break;
            default:
                break;
        }
    }
    return proc;
}

SkBlitMask::BlitLCD16RowProc SkBlitMask::PlatformBlitRowProcs16(bool isOpaque) {
    if (cachedHasSSE2()) {
        if (isOpaque) {
            return SkBlitLCD16OpaqueRow_SSE2;
        } else {
            return SkBlitLCD16Row_SSE2;
        }
    } else {
        return NULL;
    }

}
SkBlitMask::RowProc SkBlitMask::PlatformRowProcs(SkBitmap::Config dstConfig,
                                                 SkMask::Format maskFormat,
                                                 RowFlags flags) {
    return NULL;
}

SkMemset16Proc SkMemset16GetPlatformProc() {
    if (cachedHasSSE2()) {
        return sk_memset16_SSE2;
    } else {
        return NULL;
    }
}

SkMemset32Proc SkMemset32GetPlatformProc() {
    if (cachedHasSSE2()) {
        return sk_memset32_SSE2;
    } else {
        return NULL;
    }
}

SkBlitRow::ColorRectProc PlatformColorRectProcFactory(); // suppress warning

SkBlitRow::ColorRectProc PlatformColorRectProcFactory() {
    if (cachedHasSSE2()) {
        return ColorRect32_SSE2;
    } else {
        return NULL;
    }
}
<commit_msg>Let hasSSSE3 return false for the Android framework, if the CPU level check doesn't support SSSE3.<commit_after>/*
 * Copyright 2009 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBitmapProcState_opts_SSE2.h"
#include "SkBitmapProcState_opts_SSSE3.h"
#include "SkBitmapFilter_opts_SSE2.h"
#include "SkBlitMask.h"
#include "SkBlitRow.h"
#include "SkBlitRect_opts_SSE2.h"
#include "SkBlitRow_opts_SSE2.h"
#include "SkUtils_opts_SSE2.h"
#include "SkUtils.h"

#include "SkRTConf.h"

#if defined(_MSC_VER) && defined(_WIN64)
#include <intrin.h>
#endif

/* This file must *not* be compiled with -msse or -msse2, otherwise
   gcc may generate sse2 even for scalar ops (and thus give an invalid
   instruction on Pentium3 on the code below).  Only files named *_SSE2.cpp
   in this directory should be compiled with -msse2. */

#ifdef _MSC_VER
static inline void getcpuid(int info_type, int info[4]) {
#if defined(_WIN64)
    __cpuid(info, info_type);
#else
    __asm {
        mov    eax, [info_type]
        cpuid
        mov    edi, [info]
        mov    [edi], eax
        mov    [edi+4], ebx
        mov    [edi+8], ecx
        mov    [edi+12], edx
    }
#endif
}
#else
#if defined(__x86_64__)
static inline void getcpuid(int info_type, int info[4]) {
    asm volatile (
        "cpuid \n\t"
        : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3])
        : "a"(info_type)
    );
}
#else
static inline void getcpuid(int info_type, int info[4]) {
    // We save and restore ebx, so this code can be compatible with -fPIC
    asm volatile (
        "pushl %%ebx      \n\t"
        "cpuid            \n\t"
        "movl %%ebx, %1   \n\t"
        "popl %%ebx       \n\t"
        : "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
        : "a"(info_type)
    );
}
#endif
#endif

#if defined(__x86_64__) || defined(_WIN64) || SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
/* All x86_64 machines have SSE2, or we know it's supported at compile time,  so don't even bother checking. */
static inline bool hasSSE2() {
    return true;
}
#else

static inline bool hasSSE2() {
    int cpu_info[4] = { 0 };
    getcpuid(1, cpu_info);
    return (cpu_info[3] & (1<<26)) != 0;
}
#endif

#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
/* If we know SSSE3 is supported at compile time, don't even bother checking. */
static inline bool hasSSSE3() {
    return true;
}
#elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
/* For the Android framework, if the device does not support SSSE3, the
   compiler will not supply the required -mssse3 option.  Thus, we return
   false here.  */
static inline bool hasSSSE3() {
    return false;
}
#else

static inline bool hasSSSE3() {
    int cpu_info[4] = { 0 };
    getcpuid(1, cpu_info);
    return (cpu_info[2] & 0x200) != 0;
}
#endif

static bool cachedHasSSE2() {
    static bool gHasSSE2 = hasSSE2();
    return gHasSSE2;
}

static bool cachedHasSSSE3() {
    static bool gHasSSSE3 = hasSSSE3();
    return gHasSSSE3;
}

SK_CONF_DECLARE( bool, c_hqfilter_sse, "bitmap.filter.highQualitySSE", false, "Use SSE optimized version of high quality image filters");

void SkBitmapProcState::platformConvolutionProcs() {
    if (cachedHasSSE2()) {
        fConvolutionProcs->fExtraHorizontalReads = 3;
        fConvolutionProcs->fConvolveVertically = &convolveVertically_SSE2;
        fConvolutionProcs->fConvolve4RowsHorizontally = &convolve4RowsHorizontally_SSE2;
        fConvolutionProcs->fConvolveHorizontally = &convolveHorizontally_SSE2;
        fConvolutionProcs->fApplySIMDPadding = &applySIMDPadding_SSE2;
    }
}

void SkBitmapProcState::platformProcs() {
    if (cachedHasSSSE3()) {
        if (fSampleProc32 == S32_opaque_D32_filter_DX) {
            fSampleProc32 = S32_opaque_D32_filter_DX_SSSE3;
        } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
            fSampleProc32 = S32_alpha_D32_filter_DX_SSSE3;
        }

        if (fSampleProc32 == S32_opaque_D32_filter_DXDY) {
            fSampleProc32 = S32_opaque_D32_filter_DXDY_SSSE3;
        } else if (fSampleProc32 == S32_alpha_D32_filter_DXDY) {
            fSampleProc32 = S32_alpha_D32_filter_DXDY_SSSE3;
        }
    } else if (cachedHasSSE2()) {
        if (fSampleProc32 == S32_opaque_D32_filter_DX) {
            fSampleProc32 = S32_opaque_D32_filter_DX_SSE2;
        } else if (fSampleProc32 == S32_alpha_D32_filter_DX) {
            fSampleProc32 = S32_alpha_D32_filter_DX_SSE2;
        }

        if (fSampleProc16 == S32_D16_filter_DX) {
            fSampleProc16 = S32_D16_filter_DX_SSE2;
        }
    }

    if (cachedHasSSSE3() || cachedHasSSE2()) {
        if (fMatrixProc == ClampX_ClampY_filter_scale) {
            fMatrixProc = ClampX_ClampY_filter_scale_SSE2;
        } else if (fMatrixProc == ClampX_ClampY_nofilter_scale) {
            fMatrixProc = ClampX_ClampY_nofilter_scale_SSE2;
        }

        if (fMatrixProc == ClampX_ClampY_filter_affine) {
            fMatrixProc = ClampX_ClampY_filter_affine_SSE2;
        } else if (fMatrixProc == ClampX_ClampY_nofilter_affine) {
            fMatrixProc = ClampX_ClampY_nofilter_affine_SSE2;
        }
        if (c_hqfilter_sse) {
            if (fShaderProc32 == highQualityFilter) {
                fShaderProc32 = highQualityFilter_SSE2;
            }
        }
    }
}

static SkBlitRow::Proc32 platform_32_procs[] = {
    NULL,                               // S32_Opaque,
    S32_Blend_BlitRow32_SSE2,           // S32_Blend,
    S32A_Opaque_BlitRow32_SSE2,         // S32A_Opaque
    S32A_Blend_BlitRow32_SSE2,          // S32A_Blend,
};

SkBlitRow::Proc SkBlitRow::PlatformProcs565(unsigned flags) {
    return NULL;
}

SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() {
    if (cachedHasSSE2()) {
        return Color32_SSE2;
    } else {
        return NULL;
    }
}

SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
    if (cachedHasSSE2()) {
        return platform_32_procs[flags];
    } else {
        return NULL;
    }
}

SkBlitMask::ColorProc SkBlitMask::PlatformColorProcs(SkBitmap::Config dstConfig,
                                                     SkMask::Format maskFormat,
                                                     SkColor color) {
    if (SkMask::kA8_Format != maskFormat) {
        return NULL;
    }

    ColorProc proc = NULL;
    if (cachedHasSSE2()) {
        switch (dstConfig) {
            case SkBitmap::kARGB_8888_Config:
                // The SSE2 version is not (yet) faster for black, so we check
                // for that.
                if (SK_ColorBLACK != color) {
                    proc = SkARGB32_A8_BlitMask_SSE2;
                }
                break;
            default:
                break;
        }
    }
    return proc;
}

SkBlitMask::BlitLCD16RowProc SkBlitMask::PlatformBlitRowProcs16(bool isOpaque) {
    if (cachedHasSSE2()) {
        if (isOpaque) {
            return SkBlitLCD16OpaqueRow_SSE2;
        } else {
            return SkBlitLCD16Row_SSE2;
        }
    } else {
        return NULL;
    }

}
SkBlitMask::RowProc SkBlitMask::PlatformRowProcs(SkBitmap::Config dstConfig,
                                                 SkMask::Format maskFormat,
                                                 RowFlags flags) {
    return NULL;
}

SkMemset16Proc SkMemset16GetPlatformProc() {
    if (cachedHasSSE2()) {
        return sk_memset16_SSE2;
    } else {
        return NULL;
    }
}

SkMemset32Proc SkMemset32GetPlatformProc() {
    if (cachedHasSSE2()) {
        return sk_memset32_SSE2;
    } else {
        return NULL;
    }
}

SkBlitRow::ColorRectProc PlatformColorRectProcFactory(); // suppress warning

SkBlitRow::ColorRectProc PlatformColorRectProcFactory() {
    if (cachedHasSSE2()) {
        return ColorRect32_SSE2;
    } else {
        return NULL;
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: pe_file2.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2005-01-27 11:31:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef LUIDL_PE_FILE2_HXX
#define LUIDL_PE_FILE2_HXX

// USED SERVICES
    // BASE CLASSES
#include <s2_luidl/parsenv2.hxx>
#include <s2_luidl/pestate.hxx>
    // COMPONENTS
    // PARAMETERS

namespace ary
{
namespace idl
{
class Module;
}   // namespace idl
}   // namespace ary

namespace csi
{
namespace uidl
{

class TokenDistributor;
class PE_Service;
class PE_Singleton;
class PE_Interface;
class PE_Struct;
class PE_Exception;
class PE_Constant;
class PE_Enum;
class PE_Typedef;

class PE_File : public UnoIDL_PE,
                public ParseEnvState
{
  public:
                        PE_File(
                            TokenDistributor &  i_rTokenAdmin,
                            const ParserInfo &  i_parseInfo );
    virtual void        EstablishContacts(
                            UnoIDL_PE *         io_pParentPE,
                            ary::n22::Repository &  io_rRepository,
                            TokenProcessing_Result &
                                                o_rResult );
                        ~PE_File();

    virtual void        ProcessToken(
                            const Token &       i_rToken );

    virtual void        Process_Identifier(
                            const TokIdentifier &
                                                i_rToken );
    virtual void        Process_Punctuation(
                            const TokPunctuation &
                                                i_rToken );
    virtual void        Process_MetaType(
                            const TokMetaType & i_rToken );
    virtual void        Process_Stereotype(
                            const TokStereotype &
                                                i_rToken );
    virtual void        Process_Default();

  private:
    enum E_State
    {
        e_none,
        e_std,
        wait_for_module,
        wait_for_module_bracket,
        wait_for_module_semicolon,
        in_sub_pe,
        on_default
    };

    virtual void        InitData();
    virtual void        TransferData();
    virtual void        ReceiveData();
    virtual UnoIDL_PE & MyPE();
    virtual const ary::idl::Module &
                        CurNamespace() const;
    virtual const ParserInfo &
                        ParseInfo() const;
    // DATA
    TokenDistributor *  pTokenAdmin;
    Dyn<PE_Service>     pPE_Service;
    Dyn<PE_Singleton>   pPE_Singleton;
    Dyn<PE_Interface>   pPE_Interface;
    Dyn<PE_Struct>      pPE_Struct;
    Dyn<PE_Exception>   pPE_Exception;
    Dyn<PE_Constant>    pPE_Constant;
    Dyn<PE_Enum>        pPE_Enum;
    Dyn<PE_Typedef>     pPE_Typedef;

    const ary::idl::Module *
                        pCurNamespace;
    const ParserInfo *  pParseInfo;

    E_State             eState;
    uintt               nBracketCount_inDefMode;
};

}   // namespace uidl
}   // namespace csi

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.4.16); FILE MERGED 2005/09/05 13:12:41 rt 1.4.16.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pe_file2.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 19:01:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef LUIDL_PE_FILE2_HXX
#define LUIDL_PE_FILE2_HXX

// USED SERVICES
    // BASE CLASSES
#include <s2_luidl/parsenv2.hxx>
#include <s2_luidl/pestate.hxx>
    // COMPONENTS
    // PARAMETERS

namespace ary
{
namespace idl
{
class Module;
}   // namespace idl
}   // namespace ary

namespace csi
{
namespace uidl
{

class TokenDistributor;
class PE_Service;
class PE_Singleton;
class PE_Interface;
class PE_Struct;
class PE_Exception;
class PE_Constant;
class PE_Enum;
class PE_Typedef;

class PE_File : public UnoIDL_PE,
                public ParseEnvState
{
  public:
                        PE_File(
                            TokenDistributor &  i_rTokenAdmin,
                            const ParserInfo &  i_parseInfo );
    virtual void        EstablishContacts(
                            UnoIDL_PE *         io_pParentPE,
                            ary::n22::Repository &  io_rRepository,
                            TokenProcessing_Result &
                                                o_rResult );
                        ~PE_File();

    virtual void        ProcessToken(
                            const Token &       i_rToken );

    virtual void        Process_Identifier(
                            const TokIdentifier &
                                                i_rToken );
    virtual void        Process_Punctuation(
                            const TokPunctuation &
                                                i_rToken );
    virtual void        Process_MetaType(
                            const TokMetaType & i_rToken );
    virtual void        Process_Stereotype(
                            const TokStereotype &
                                                i_rToken );
    virtual void        Process_Default();

  private:
    enum E_State
    {
        e_none,
        e_std,
        wait_for_module,
        wait_for_module_bracket,
        wait_for_module_semicolon,
        in_sub_pe,
        on_default
    };

    virtual void        InitData();
    virtual void        TransferData();
    virtual void        ReceiveData();
    virtual UnoIDL_PE & MyPE();
    virtual const ary::idl::Module &
                        CurNamespace() const;
    virtual const ParserInfo &
                        ParseInfo() const;
    // DATA
    TokenDistributor *  pTokenAdmin;
    Dyn<PE_Service>     pPE_Service;
    Dyn<PE_Singleton>   pPE_Singleton;
    Dyn<PE_Interface>   pPE_Interface;
    Dyn<PE_Struct>      pPE_Struct;
    Dyn<PE_Exception>   pPE_Exception;
    Dyn<PE_Constant>    pPE_Constant;
    Dyn<PE_Enum>        pPE_Enum;
    Dyn<PE_Typedef>     pPE_Typedef;

    const ary::idl::Module *
                        pCurNamespace;
    const ParserInfo *  pParseInfo;

    E_State             eState;
    uintt               nBracketCount_inDefMode;
};

}   // namespace uidl
}   // namespace csi

#endif

<|endoftext|>


<commit_before>//===- bugpoint.cpp - The LLVM BugPoint utility ---------------------------===//
//
// This program is an automated compiler debugger tool.  It is used to narrow
// down miscompilations and crash problems to a specific pass in the compiler,
// and the specific Module or Function input that is causing the problem.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "Support/CommandLine.h"
#include "llvm/Support/PassNameParser.h"

static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
               cl::desc("<input llvm ll/bc files>"));

// The AnalysesList is automatically populated with registered Passes by the
// PassNameParser.
//
static cl::list<const PassInfo*, bool, PassNameParser>
PassList(cl::desc("Passes available:"), cl::ZeroOrMore);

//cl::list<std::string>
//InputArgv(cl::ConsumeAfter, cl::desc("<program arguments>..."));

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv);

  BugDriver D(argv[0]);
  if (D.addSources(InputFilenames)) return 1;
  D.addPasses(PassList.begin(), PassList.end());

  return D.run();
}
<commit_msg>Add variable to capture arguments that should be passed to the user program This is unused so far.<commit_after>//===- bugpoint.cpp - The LLVM BugPoint utility ---------------------------===//
//
// This program is an automated compiler debugger tool.  It is used to narrow
// down miscompilations and crash problems to a specific pass in the compiler,
// and the specific Module or Function input that is causing the problem.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "Support/CommandLine.h"
#include "llvm/Support/PassNameParser.h"

static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
               cl::desc("<input llvm ll/bc files>"));

// The AnalysesList is automatically populated with registered Passes by the
// PassNameParser.
//
static cl::list<const PassInfo*, bool, PassNameParser>
PassList(cl::desc("Passes available:"), cl::ZeroOrMore);

// Anything specified after the --args option are taken as arguments to the
// program being debugged.
cl::list<std::string>
InputArgv("args", cl::Positional, cl::desc("<program arguments>..."),
          cl::ZeroOrMore);

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv);

  BugDriver D(argv[0]);
  if (D.addSources(InputFilenames)) return 1;
  D.addPasses(PassList.begin(), PassList.end());

  return D.run();
}
<|endoftext|>


<commit_before>//===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This program is an automated compiler debugger tool.  It is used to narrow
// down miscompilations and crash problems to a specific pass in the compiler,
// and the specific Module or Function input that is causing the problem.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ToolRunner.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Valgrind.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

// Enable this macro to debug bugpoint itself.
//#define DEBUG_BUGPOINT 1

using namespace llvm;

static cl::opt<bool>
    FindBugs("find-bugs", cl::desc("Run many different optimization sequences "
                                   "on program to find bugs"),
             cl::init(false));

static cl::list<std::string>
    InputFilenames(cl::Positional, cl::OneOrMore,
                   cl::desc("<input llvm ll/bc files>"));

static cl::opt<unsigned> TimeoutValue(
    "timeout", cl::init(300), cl::value_desc("seconds"),
    cl::desc("Number of seconds program is allowed to run before it "
             "is killed (default is 300s), 0 disables timeout"));

static cl::opt<int>
    MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"),
                cl::desc("Maximum amount of memory to use. 0 disables check."
                         " Defaults to 400MB (800MB under valgrind)."));

static cl::opt<bool>
    UseValgrind("enable-valgrind",
                cl::desc("Run optimizations through valgrind"));

// The AnalysesList is automatically populated with registered Passes by the
// PassNameParser.
//
static cl::list<const PassInfo *, bool, PassNameParser>
    PassList(cl::desc("Passes available:"), cl::ZeroOrMore);

static cl::opt<bool>
    StandardLinkOpts("std-link-opts",
                     cl::desc("Include the standard link time optimizations"));

static cl::opt<bool>
    OptLevelO1("O1", cl::desc("Optimization level 1. Identical to 'opt -O1'"));

static cl::opt<bool>
    OptLevelO2("O2", cl::desc("Optimization level 2. Identical to 'opt -O2'"));

static cl::opt<bool> OptLevelOs(
    "Os",
    cl::desc(
        "Like -O2 with extra optimizations for size. Similar to clang -Os"));

static cl::opt<bool>
    OptLevelO3("O3", cl::desc("Optimization level 3. Identical to 'opt -O3'"));

static cl::opt<std::string>
    OverrideTriple("mtriple", cl::desc("Override target triple for module"));

/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
bool llvm::BugpointIsInterrupted = false;

#ifndef DEBUG_BUGPOINT
static void BugpointInterruptFunction() { BugpointIsInterrupted = true; }
#endif

// Hack to capture a pass list.
namespace {
class AddToDriver : public legacy::FunctionPassManager {
  BugDriver &D;

public:
  AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {}

  void add(Pass *P) override {
    const void *ID = P->getPassID();
    const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
    D.addPass(PI->getPassArgument());
  }
};
}

#ifdef LINK_POLLY_INTO_TOOLS
namespace polly {
void initializePollyPasses(llvm::PassRegistry &Registry);
}
#endif

int main(int argc, char **argv) {
#ifndef DEBUG_BUGPOINT
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
#endif

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

#ifdef LINK_POLLY_INTO_TOOLS
  polly::initializePollyPasses(Registry);
#endif

  if (std::getenv("bar") == (char*) -1) {
    InitializeAllTargets();
    InitializeAllTargetMCs();
    InitializeAllAsmPrinters();
    InitializeAllAsmParsers();
  }

  cl::ParseCommandLineOptions(argc, argv,
                              "LLVM automatic testcase reducer. See\nhttp://"
                              "llvm.org/cmds/bugpoint.html"
                              " for more information.\n");
#ifndef DEBUG_BUGPOINT
  sys::SetInterruptFunction(BugpointInterruptFunction);
#endif

  LLVMContext Context;
  // If we have an override, set it and then track the triple we want Modules
  // to use.
  if (!OverrideTriple.empty()) {
    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
  }

  if (MemoryLimit < 0) {
    // Set the default MemoryLimit.  Be sure to update the flag's description if
    // you change this.
    if (sys::RunningOnValgrind() || UseValgrind)
      MemoryLimit = 800;
    else
      MemoryLimit = 400;
  }

  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind,
              Context);
  if (D.addSources(InputFilenames))
    return 1;

  AddToDriver PM(D);

  if (StandardLinkOpts) {
    PassManagerBuilder Builder;
    Builder.Inliner = createFunctionInliningPass();
    Builder.populateLTOPassManager(PM);
  }

  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    PassManagerBuilder Builder;
    if (OptLevelO1)
      Builder.Inliner = createAlwaysInlinerLegacyPass();
    else if (OptLevelOs || OptLevelO2)
      Builder.Inliner = createFunctionInliningPass(
          2, OptLevelOs ? 1 : 0, false);
    else
      Builder.Inliner = createFunctionInliningPass(275);
    Builder.populateFunctionPassManager(PM);
    Builder.populateModulePassManager(PM);
  }

  for (const PassInfo *PI : PassList)
    D.addPass(PI->getPassArgument());

// Bugpoint has the ability of generating a plethora of core files, so to
// avoid filling up the disk, we prevent it
#ifndef DEBUG_BUGPOINT
  sys::Process::PreventCoreFiles();
#endif

  if (Error E = D.run()) {
    errs() << toString(std::move(E));
    return 1;
  }
  return 0;
}
<commit_msg>Fix check-llvm on kernel 4.9+ with asan or msan<commit_after>//===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This program is an automated compiler debugger tool.  It is used to narrow
// down miscompilations and crash problems to a specific pass in the compiler,
// and the specific Module or Function input that is causing the problem.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ToolRunner.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Valgrind.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

// Enable this macro to debug bugpoint itself.
//#define DEBUG_BUGPOINT 1

using namespace llvm;

static cl::opt<bool>
    FindBugs("find-bugs", cl::desc("Run many different optimization sequences "
                                   "on program to find bugs"),
             cl::init(false));

static cl::list<std::string>
    InputFilenames(cl::Positional, cl::OneOrMore,
                   cl::desc("<input llvm ll/bc files>"));

static cl::opt<unsigned> TimeoutValue(
    "timeout", cl::init(300), cl::value_desc("seconds"),
    cl::desc("Number of seconds program is allowed to run before it "
             "is killed (default is 300s), 0 disables timeout"));

static cl::opt<int> MemoryLimit(
    "mlimit", cl::init(-1), cl::value_desc("MBytes"),
    cl::desc("Maximum amount of memory to use. 0 disables check. Defaults to "
             "400MB (800MB under valgrind, 0 with sanitizers)."));

static cl::opt<bool>
    UseValgrind("enable-valgrind",
                cl::desc("Run optimizations through valgrind"));

// The AnalysesList is automatically populated with registered Passes by the
// PassNameParser.
//
static cl::list<const PassInfo *, bool, PassNameParser>
    PassList(cl::desc("Passes available:"), cl::ZeroOrMore);

static cl::opt<bool>
    StandardLinkOpts("std-link-opts",
                     cl::desc("Include the standard link time optimizations"));

static cl::opt<bool>
    OptLevelO1("O1", cl::desc("Optimization level 1. Identical to 'opt -O1'"));

static cl::opt<bool>
    OptLevelO2("O2", cl::desc("Optimization level 2. Identical to 'opt -O2'"));

static cl::opt<bool> OptLevelOs(
    "Os",
    cl::desc(
        "Like -O2 with extra optimizations for size. Similar to clang -Os"));

static cl::opt<bool>
    OptLevelO3("O3", cl::desc("Optimization level 3. Identical to 'opt -O3'"));

static cl::opt<std::string>
    OverrideTriple("mtriple", cl::desc("Override target triple for module"));

/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
bool llvm::BugpointIsInterrupted = false;

#ifndef DEBUG_BUGPOINT
static void BugpointInterruptFunction() { BugpointIsInterrupted = true; }
#endif

// Hack to capture a pass list.
namespace {
class AddToDriver : public legacy::FunctionPassManager {
  BugDriver &D;

public:
  AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {}

  void add(Pass *P) override {
    const void *ID = P->getPassID();
    const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
    D.addPass(PI->getPassArgument());
  }
};
}

#ifdef LINK_POLLY_INTO_TOOLS
namespace polly {
void initializePollyPasses(llvm::PassRegistry &Registry);
}
#endif

int main(int argc, char **argv) {
#ifndef DEBUG_BUGPOINT
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
#endif

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

#ifdef LINK_POLLY_INTO_TOOLS
  polly::initializePollyPasses(Registry);
#endif

  if (std::getenv("bar") == (char*) -1) {
    InitializeAllTargets();
    InitializeAllTargetMCs();
    InitializeAllAsmPrinters();
    InitializeAllAsmParsers();
  }

  cl::ParseCommandLineOptions(argc, argv,
                              "LLVM automatic testcase reducer. See\nhttp://"
                              "llvm.org/cmds/bugpoint.html"
                              " for more information.\n");
#ifndef DEBUG_BUGPOINT
  sys::SetInterruptFunction(BugpointInterruptFunction);
#endif

  LLVMContext Context;
  // If we have an override, set it and then track the triple we want Modules
  // to use.
  if (!OverrideTriple.empty()) {
    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
  }

  if (MemoryLimit < 0) {
    // Set the default MemoryLimit.  Be sure to update the flag's description if
    // you change this.
    if (sys::RunningOnValgrind() || UseValgrind)
      MemoryLimit = 800;
    else
      MemoryLimit = 400;
#if (LLVM_ADDRESS_SANITIZER_BUILD || LLVM_MEMORY_SANITIZER_BUILD ||            \
     LLVM_THREAD_SANITIZER_BUILD)
    // Starting from kernel 4.9 memory allocated with mmap is counted against
    // RLIMIT_DATA. Sanitizers need to allocate tens of terabytes for shadow.
    MemoryLimit = 0;
#endif
  }

  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind,
              Context);
  if (D.addSources(InputFilenames))
    return 1;

  AddToDriver PM(D);

  if (StandardLinkOpts) {
    PassManagerBuilder Builder;
    Builder.Inliner = createFunctionInliningPass();
    Builder.populateLTOPassManager(PM);
  }

  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    PassManagerBuilder Builder;
    if (OptLevelO1)
      Builder.Inliner = createAlwaysInlinerLegacyPass();
    else if (OptLevelOs || OptLevelO2)
      Builder.Inliner = createFunctionInliningPass(
          2, OptLevelOs ? 1 : 0, false);
    else
      Builder.Inliner = createFunctionInliningPass(275);
    Builder.populateFunctionPassManager(PM);
    Builder.populateModulePassManager(PM);
  }

  for (const PassInfo *PI : PassList)
    D.addPass(PI->getPassArgument());

// Bugpoint has the ability of generating a plethora of core files, so to
// avoid filling up the disk, we prevent it
#ifndef DEBUG_BUGPOINT
  sys::Process::PreventCoreFiles();
#endif

  if (Error E = D.run()) {
    errs() << toString(std::move(E));
    return 1;
  }
  return 0;
}
<|endoftext|>