<commit_before>#include <cstdlib>
#include <SDL2/SDL.h>
#include "KeyListener.h"

KeyListener::KeyListener(){}

KeyListener::~KeyListener(){}

int KeyListener::query(){

    // message processing loop
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        // check for messages
        switch (event.type)
        {
            // exit if the window is closed
            case SDL_QUIT:
                return 1;
                break;

            // check for keypresses
            case SDL_KEYDOWN:
            {
                    // exit if ESCAPE is pressed
                if (event.key.keysym.sym == SDL_SCANCODE_ESCAPE)
                        return 1;
                break;
            }
        } // end switch
    } // end of message processing
    return 0;
}

int KeyListener::getKeys(){
    const Uint8 *keys = SDL_GetKeyboardState(NULL);
     // Handle input
        if (keys[SDL_SCANCODE_LEFT] && !keys[SDL_SCANCODE_RIGHT])
            return 1;
        else if (keys[SDL_SCANCODE_RIGHT] && !keys[SDL_SCANCODE_LEFT])
            return 2;
        else
            return 0;

}

int KeyListener::save(){

    SDL_Event event;
    if (event.type == SDL_KEYDOWN)
    {
        if (event.key.keysym.sym == SDL_SCANCODE_S)
            return 1;
        else if(event.key.keysym.sym == SDL_SCANCODE_L)
            return 2;
    }
    return 0;
}
<commit_msg>Keyboard events are now properly handled.<commit_after>#include <cstdlib>
#include <SDL2/SDL.h>
#include "KeyListener.h"

KeyListener::KeyListener(){}

KeyListener::~KeyListener(){}

int KeyListener::query(){

    // message processing loop
    SDL_Event event;
    const Uint8* keys = SDL_GetKeyboardState(NULL);
    while (SDL_PollEvent(&event))
    {
        // check for messages
        switch (event.type)
        {
            // exit if the window is closed
            case SDL_QUIT:
                return 1;
                break;

            // check for keypresses
            case SDL_KEYDOWN:
            {
                    // exit if ESCAPE is pressed
                if (keys[SDL_SCANCODE_ESCAPE])
                        return 1;
                break;
            }
        } // end switch
    } // end of message processing
    return 0;
}

int KeyListener::getKeys(){
    const Uint8 *keys = SDL_GetKeyboardState(NULL);

    SDL_Event event;

    while(SDL_PollEvent(&event)){
     // Handle input
        if (keys[SDL_SCANCODE_LEFT] && !keys[SDL_SCANCODE_RIGHT])
            return 1;
        else if (keys[SDL_SCANCODE_RIGHT] && !keys[SDL_SCANCODE_LEFT])
            return 2;
        else
            return 0;
    }
}

int KeyListener::save(){

    const Uint8 *keys = SDL_GetKeyboardState(NULL);
    SDL_Event event;
    while(SDL_PollEvent(&event)){
        if (event.type == SDL_KEYDOWN)
        {
        if (keys[SDL_SCANCODE_S])
            return 1;
        else if(keys[SDL_SCANCODE_L])
            return 2;
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>//===-- ScalarTest.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"

#include "lldb/Core/Scalar.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb_private;

TEST(ScalarTest, RightShiftOperator) {
  int a = 0x00001000;
  int b = 0xFFFFFFFF;
  int c = 4;
  Scalar a_scalar(a);
  Scalar b_scalar(b);
  Scalar c_scalar(c);
  ASSERT_EQ(a >> c, a_scalar >> c_scalar);
  ASSERT_EQ(b >> c, b_scalar >> c_scalar);
}

TEST(ScalarTest, GetBytes) {
  int a = 0x01020304;
  long long b = 0x0102030405060708LL;
  float c = 1234567.89e32;
  double d = 1234567.89e42;
  char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  char f[32] = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16,
                17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
  Scalar a_scalar(a);
  Scalar b_scalar(b);
  Scalar c_scalar(c);
  Scalar d_scalar(d);
  Scalar e_scalar;
  Scalar f_scalar;
  DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(),
                       sizeof(void *));
  Status e_error =
      e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e));
  DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(),
                       sizeof(void *));
  Status f_error =
      f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f));
  ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a)));
  ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b)));
  ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c)));
  ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d)));
  ASSERT_EQ(0, e_error.Fail());
  ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e)));
  ASSERT_EQ(0, f_error.Fail());
  ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f)));
}

TEST(ScalarTest, CastOperations) {
  long long a = 0xf1f2f3f4f5f6f7f8LL;
  Scalar a_scalar(a);
  ASSERT_EQ((signed char)a, a_scalar.SChar());
  ASSERT_EQ((unsigned char)a, a_scalar.UChar());
  ASSERT_EQ((signed short)a, a_scalar.SShort());
  ASSERT_EQ((unsigned short)a, a_scalar.UShort());
  ASSERT_EQ((signed int)a, a_scalar.SInt());
  ASSERT_EQ((unsigned int)a, a_scalar.UInt());
  ASSERT_EQ((signed long)a, a_scalar.SLong());
  ASSERT_EQ((unsigned long)a, a_scalar.ULong());
  ASSERT_EQ((signed long long)a, a_scalar.SLongLong());
  ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong());

  int a2 = 23;
  Scalar a2_scalar(a2);
  ASSERT_EQ((float)a2, a2_scalar.Float());
  ASSERT_EQ((double)a2, a2_scalar.Double());
  ASSERT_EQ((long double)a2, a2_scalar.LongDouble());
}

TEST(ScalarTest, ExtractBitfield) {
  uint32_t len = sizeof(long long) * 8;

  long long a1 = 0xf1f2f3f4f5f6f7f8LL;
  long long b1 = 0xff1f2f3f4f5f6f7fLL;
  Scalar s_scalar(a1);
  ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
  ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
  ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
  ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
  ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
  ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1)));

  unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
  unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
  Scalar u_scalar(a2);
  ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
  ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
  ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
  ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
  ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
  ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2)));
}

template <typename T> static std::string ScalarGetValue(T value) {
  StreamString stream;
  Scalar(value).GetValue(&stream, false);
  return stream.GetString();
}

TEST(ScalarTest, GetValue) {
  EXPECT_EQ("12345", ScalarGetValue<signed short>(12345));
  EXPECT_EQ("-12345", ScalarGetValue<signed short>(-12345));
  EXPECT_EQ("12345", ScalarGetValue<unsigned short>(12345));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned short>::max()),
            ScalarGetValue(std::numeric_limits<unsigned short>::max()));

  EXPECT_EQ("12345", ScalarGetValue<signed int>(12345));
  EXPECT_EQ("-12345", ScalarGetValue<signed int>(-12345));
  EXPECT_EQ("12345", ScalarGetValue<unsigned int>(12345));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned int>::max()),
            ScalarGetValue(std::numeric_limits<unsigned int>::max()));

  EXPECT_EQ("12345678", ScalarGetValue<signed long>(12345678L));
  EXPECT_EQ("-12345678", ScalarGetValue<signed long>(-12345678L));
  EXPECT_EQ("12345678", ScalarGetValue<unsigned long>(12345678UL));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long>::max()),
            ScalarGetValue(std::numeric_limits<unsigned long>::max()));

  EXPECT_EQ("1234567890123", ScalarGetValue<signed long long>(1234567890123LL));
  EXPECT_EQ("-1234567890123",
            ScalarGetValue<signed long long>(-1234567890123LL));
  EXPECT_EQ("1234567890123",
            ScalarGetValue<unsigned long long>(1234567890123ULL));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()),
            ScalarGetValue(std::numeric_limits<unsigned long long>::max()));
}

TEST(ScalarTest, Division) {
  Scalar lhs(5.0);
  Scalar rhs(2.0);
  Scalar r = lhs / rhs;
  EXPECT_TRUE(r.IsValid());
  EXPECT_EQ(r, Scalar(2.5));
}

TEST(ScalarTest, Promotion) {
  static Scalar::Type int_types[] = {
      Scalar::e_sint,    Scalar::e_uint,      Scalar::e_slong,
      Scalar::e_ulong,   Scalar::e_slonglong, Scalar::e_ulonglong,
      Scalar::e_sint128, Scalar::e_uint128,   Scalar::e_sint256,
      Scalar::e_uint256,
      Scalar::e_void // sentinel
  };

  static Scalar::Type float_types[] = {
      Scalar::e_float, Scalar::e_double, Scalar::e_long_double,
      Scalar::e_void // sentinel
  };

  for (int i = 0; int_types[i] != Scalar::e_void; ++i) {
    for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
      Scalar lhs(2);
      EXPECT_TRUE(lhs.Promote(int_types[i])) << "int promotion #" << i;
      Scalar rhs(0.5f);
      EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
      Scalar x(2.5f);
      EXPECT_TRUE(x.Promote(float_types[j]));
      EXPECT_EQ(lhs + rhs, x);
    }
  }

  for (int i = 0; float_types[i] != Scalar::e_void; ++i) {
    for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
      Scalar lhs(2);
      EXPECT_TRUE(lhs.Promote(float_types[i])) << "float promotion #" << i;
      Scalar rhs(0.5f);
      EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
      Scalar x(2.5f);
      EXPECT_TRUE(x.Promote(float_types[j]));
      EXPECT_EQ(lhs + rhs, x);
    }
  }
}
<commit_msg>Fix narrowing warning by appending `f` to literal constant.<commit_after>//===-- ScalarTest.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"

#include "lldb/Core/Scalar.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb_private;

TEST(ScalarTest, RightShiftOperator) {
  int a = 0x00001000;
  int b = 0xFFFFFFFF;
  int c = 4;
  Scalar a_scalar(a);
  Scalar b_scalar(b);
  Scalar c_scalar(c);
  ASSERT_EQ(a >> c, a_scalar >> c_scalar);
  ASSERT_EQ(b >> c, b_scalar >> c_scalar);
}

TEST(ScalarTest, GetBytes) {
  int a = 0x01020304;
  long long b = 0x0102030405060708LL;
  float c = 1234567.89e32f;
  double d = 1234567.89e42;
  char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  char f[32] = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16,
                17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
  Scalar a_scalar(a);
  Scalar b_scalar(b);
  Scalar c_scalar(c);
  Scalar d_scalar(d);
  Scalar e_scalar;
  Scalar f_scalar;
  DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(),
                       sizeof(void *));
  Status e_error =
      e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e));
  DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(),
                       sizeof(void *));
  Status f_error =
      f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f));
  ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a)));
  ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b)));
  ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c)));
  ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d)));
  ASSERT_EQ(0, e_error.Fail());
  ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e)));
  ASSERT_EQ(0, f_error.Fail());
  ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f)));
}

TEST(ScalarTest, CastOperations) {
  long long a = 0xf1f2f3f4f5f6f7f8LL;
  Scalar a_scalar(a);
  ASSERT_EQ((signed char)a, a_scalar.SChar());
  ASSERT_EQ((unsigned char)a, a_scalar.UChar());
  ASSERT_EQ((signed short)a, a_scalar.SShort());
  ASSERT_EQ((unsigned short)a, a_scalar.UShort());
  ASSERT_EQ((signed int)a, a_scalar.SInt());
  ASSERT_EQ((unsigned int)a, a_scalar.UInt());
  ASSERT_EQ((signed long)a, a_scalar.SLong());
  ASSERT_EQ((unsigned long)a, a_scalar.ULong());
  ASSERT_EQ((signed long long)a, a_scalar.SLongLong());
  ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong());

  int a2 = 23;
  Scalar a2_scalar(a2);
  ASSERT_EQ((float)a2, a2_scalar.Float());
  ASSERT_EQ((double)a2, a2_scalar.Double());
  ASSERT_EQ((long double)a2, a2_scalar.LongDouble());
}

TEST(ScalarTest, ExtractBitfield) {
  uint32_t len = sizeof(long long) * 8;

  long long a1 = 0xf1f2f3f4f5f6f7f8LL;
  long long b1 = 0xff1f2f3f4f5f6f7fLL;
  Scalar s_scalar(a1);
  ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
  ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
  ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
  ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
  ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
  ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1)));

  unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
  unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
  Scalar u_scalar(a2);
  ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
  ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
  ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
  ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
  ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
  ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2)));
}

template <typename T> static std::string ScalarGetValue(T value) {
  StreamString stream;
  Scalar(value).GetValue(&stream, false);
  return stream.GetString();
}

TEST(ScalarTest, GetValue) {
  EXPECT_EQ("12345", ScalarGetValue<signed short>(12345));
  EXPECT_EQ("-12345", ScalarGetValue<signed short>(-12345));
  EXPECT_EQ("12345", ScalarGetValue<unsigned short>(12345));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned short>::max()),
            ScalarGetValue(std::numeric_limits<unsigned short>::max()));

  EXPECT_EQ("12345", ScalarGetValue<signed int>(12345));
  EXPECT_EQ("-12345", ScalarGetValue<signed int>(-12345));
  EXPECT_EQ("12345", ScalarGetValue<unsigned int>(12345));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned int>::max()),
            ScalarGetValue(std::numeric_limits<unsigned int>::max()));

  EXPECT_EQ("12345678", ScalarGetValue<signed long>(12345678L));
  EXPECT_EQ("-12345678", ScalarGetValue<signed long>(-12345678L));
  EXPECT_EQ("12345678", ScalarGetValue<unsigned long>(12345678UL));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long>::max()),
            ScalarGetValue(std::numeric_limits<unsigned long>::max()));

  EXPECT_EQ("1234567890123", ScalarGetValue<signed long long>(1234567890123LL));
  EXPECT_EQ("-1234567890123",
            ScalarGetValue<signed long long>(-1234567890123LL));
  EXPECT_EQ("1234567890123",
            ScalarGetValue<unsigned long long>(1234567890123ULL));
  EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()),
            ScalarGetValue(std::numeric_limits<unsigned long long>::max()));
}

TEST(ScalarTest, Division) {
  Scalar lhs(5.0);
  Scalar rhs(2.0);
  Scalar r = lhs / rhs;
  EXPECT_TRUE(r.IsValid());
  EXPECT_EQ(r, Scalar(2.5));
}

TEST(ScalarTest, Promotion) {
  static Scalar::Type int_types[] = {
      Scalar::e_sint,    Scalar::e_uint,      Scalar::e_slong,
      Scalar::e_ulong,   Scalar::e_slonglong, Scalar::e_ulonglong,
      Scalar::e_sint128, Scalar::e_uint128,   Scalar::e_sint256,
      Scalar::e_uint256,
      Scalar::e_void // sentinel
  };

  static Scalar::Type float_types[] = {
      Scalar::e_float, Scalar::e_double, Scalar::e_long_double,
      Scalar::e_void // sentinel
  };

  for (int i = 0; int_types[i] != Scalar::e_void; ++i) {
    for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
      Scalar lhs(2);
      EXPECT_TRUE(lhs.Promote(int_types[i])) << "int promotion #" << i;
      Scalar rhs(0.5f);
      EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
      Scalar x(2.5f);
      EXPECT_TRUE(x.Promote(float_types[j]));
      EXPECT_EQ(lhs + rhs, x);
    }
  }

  for (int i = 0; float_types[i] != Scalar::e_void; ++i) {
    for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
      Scalar lhs(2);
      EXPECT_TRUE(lhs.Promote(float_types[i])) << "float promotion #" << i;
      Scalar rhs(0.5f);
      EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
      Scalar x(2.5f);
      EXPECT_TRUE(x.Promote(float_types[j]));
      EXPECT_EQ(lhs + rhs, x);
    }
  }
}
<|endoftext|>


<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Baozeng Ding <sploving1@gmail.com>
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/Exception.h"

#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Visibility.h"
#include "cling/Utils/Validation.h"

#include "clang/Frontend/CompilerInstance.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"

extern "C" {
/// Throw an InvalidDerefException if the Arg pointer is invalid.
///\param Interp: The interpreter that has compiled the code.
///\param Expr: The expression corresponding determining the pointer value.
///\param Arg: The pointer to be checked.
///\returns void*, const-cast from Arg, to reduce the complexity in the
/// calling AST nodes, at the expense of possibly doing a
/// T* -> const void* -> const_cast<void*> -> T* round trip.
CLING_LIB_EXPORT
void* cling_runtime_internal_throwIfInvalidPointer(void* Interp, void* Expr,
                                                   const void* Arg) {

  const clang::Expr* const E = (const clang::Expr*)Expr;

#if defined(__APPLE__) && defined(__arm64__)
  // See https://github.com/root-project/root/issues/7541 and
  // https://bugs.llvm.org/show_bug.cgi?id=49692 :
  // llvm JIT fails to catch exceptions on M1, so let's throw less.
  // This might still better than `terminate`...
  (void)Interp;
  (void)Expr;
#else
  // The isValidAddress function return true even when the pointer is
  // null thus the checks have to be done before returning successfully from the
  // function in this specific order.
  if (!Arg) {
    cling::Interpreter* I = (cling::Interpreter*)Interp;
    clang::Sema& S = I->getCI()->getSema();
    // Print a nice backtrace.
    // FIXME: re-enable once we have JIT debug symbols!
    //I->getCallbacks()->PrintStackTrace();
    throw cling::InvalidDerefException(&S, E,
          cling::InvalidDerefException::DerefType::NULL_DEREF);
  } else if (!cling::utils::isAddressValid(Arg)) {
    cling::Interpreter* I = (cling::Interpreter*)Interp;
    clang::Sema& S = I->getCI()->getSema();
    // Print a nice backtrace.
    // FIXME: re-enable once we have JIT debug symbols!
    //I->getCallbacks()->PrintStackTrace();
    throw cling::InvalidDerefException(&S, E,
          cling::InvalidDerefException::DerefType::INVALID_MEM);
  }
#endif
  return const_cast<void*>(Arg);
}
}

namespace cling {
  InterpreterException::InterpreterException(const std::string& What) :
    std::runtime_error(What), m_Sema(nullptr) {}
  InterpreterException::InterpreterException(const char* What, clang::Sema* S) :
    std::runtime_error(What), m_Sema(S) {}

  bool InterpreterException::diagnose() const { return false; }
  InterpreterException::~InterpreterException() noexcept {}

  InvalidDerefException::InvalidDerefException(clang::Sema* S,
                                               const clang::Expr* E,
                                               DerefType type)
    : InterpreterException(type == INVALID_MEM  ?
      "Trying to access a pointer that points to an invalid memory address." :
      "Trying to dereference null pointer or trying to call routine taking "
      "non-null arguments", S),
    m_Arg(E), m_Type(type) {}

  InvalidDerefException::~InvalidDerefException() noexcept {}

  bool InvalidDerefException::diagnose() const {
    // Construct custom diagnostic: warning for invalid memory address;
    // no equivalent in clang.
    if (m_Type == cling::InvalidDerefException::DerefType::INVALID_MEM) {
      clang::DiagnosticsEngine& Diags = m_Sema->getDiagnostics();
      unsigned DiagID =
        Diags.getCustomDiagID(clang::DiagnosticsEngine::Warning,
                                 "invalid memory pointer passed to a callee:");
      Diags.Report(m_Arg->getBeginLoc(), DiagID) << m_Arg->getSourceRange();
    }
    else
      m_Sema->Diag(m_Arg->getBeginLoc(), clang::diag::warn_null_arg)
        << m_Arg->getSourceRange();
    return true;
  }

  CompilationException::CompilationException(const std::string& Reason) :
    InterpreterException(Reason) {}

  CompilationException::~CompilationException() noexcept {}

  void CompilationException::throwingHandler(void * /*user_data*/,
                                             const std::string& reason,
                                             bool /*gen_crash_diag*/) {
#ifndef _MSC_VER
    throw cling::CompilationException(reason);
#endif
  }
} // end namespace cling
<commit_msg>Remove unused variables to fix build warnings on `mac11arm`<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Baozeng Ding <sploving1@gmail.com>
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Interpreter/Exception.h"

#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Visibility.h"
#include "cling/Utils/Validation.h"

#include "clang/Frontend/CompilerInstance.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"

extern "C" {
/// Throw an InvalidDerefException if the Arg pointer is invalid.
///\param Interp: The interpreter that has compiled the code.
///\param Expr: The expression corresponding determining the pointer value.
///\param Arg: The pointer to be checked.
///\returns void*, const-cast from Arg, to reduce the complexity in the
/// calling AST nodes, at the expense of possibly doing a
/// T* -> const void* -> const_cast<void*> -> T* round trip.
CLING_LIB_EXPORT
void* cling_runtime_internal_throwIfInvalidPointer(void* Interp, void* Expr,
                                                   const void* Arg) {

#if defined(__APPLE__) && defined(__arm64__)
  // See https://github.com/root-project/root/issues/7541 and
  // https://bugs.llvm.org/show_bug.cgi?id=49692 :
  // llvm JIT fails to catch exceptions on M1, so let's throw less.
  // This might still better than `terminate`...
  (void)Interp;
  (void)Expr;
#else
  const clang::Expr* const E = (const clang::Expr*)Expr;

  // The isValidAddress function return true even when the pointer is
  // null thus the checks have to be done before returning successfully from the
  // function in this specific order.
  if (!Arg) {
    cling::Interpreter* I = (cling::Interpreter*)Interp;
    clang::Sema& S = I->getCI()->getSema();
    // Print a nice backtrace.
    // FIXME: re-enable once we have JIT debug symbols!
    //I->getCallbacks()->PrintStackTrace();
    throw cling::InvalidDerefException(&S, E,
          cling::InvalidDerefException::DerefType::NULL_DEREF);
  } else if (!cling::utils::isAddressValid(Arg)) {
    cling::Interpreter* I = (cling::Interpreter*)Interp;
    clang::Sema& S = I->getCI()->getSema();
    // Print a nice backtrace.
    // FIXME: re-enable once we have JIT debug symbols!
    //I->getCallbacks()->PrintStackTrace();
    throw cling::InvalidDerefException(&S, E,
          cling::InvalidDerefException::DerefType::INVALID_MEM);
  }
#endif
  return const_cast<void*>(Arg);
}
}

namespace cling {
  InterpreterException::InterpreterException(const std::string& What) :
    std::runtime_error(What), m_Sema(nullptr) {}
  InterpreterException::InterpreterException(const char* What, clang::Sema* S) :
    std::runtime_error(What), m_Sema(S) {}

  bool InterpreterException::diagnose() const { return false; }
  InterpreterException::~InterpreterException() noexcept {}

  InvalidDerefException::InvalidDerefException(clang::Sema* S,
                                               const clang::Expr* E,
                                               DerefType type)
    : InterpreterException(type == INVALID_MEM  ?
      "Trying to access a pointer that points to an invalid memory address." :
      "Trying to dereference null pointer or trying to call routine taking "
      "non-null arguments", S),
    m_Arg(E), m_Type(type) {}

  InvalidDerefException::~InvalidDerefException() noexcept {}

  bool InvalidDerefException::diagnose() const {
    // Construct custom diagnostic: warning for invalid memory address;
    // no equivalent in clang.
    if (m_Type == cling::InvalidDerefException::DerefType::INVALID_MEM) {
      clang::DiagnosticsEngine& Diags = m_Sema->getDiagnostics();
      unsigned DiagID =
        Diags.getCustomDiagID(clang::DiagnosticsEngine::Warning,
                                 "invalid memory pointer passed to a callee:");
      Diags.Report(m_Arg->getBeginLoc(), DiagID) << m_Arg->getSourceRange();
    }
    else
      m_Sema->Diag(m_Arg->getBeginLoc(), clang::diag::warn_null_arg)
        << m_Arg->getSourceRange();
    return true;
  }

  CompilationException::CompilationException(const std::string& Reason) :
    InterpreterException(Reason) {}

  CompilationException::~CompilationException() noexcept {}

  void CompilationException::throwingHandler(void * /*user_data*/,
                                             const std::string& reason,
                                             bool /*gen_crash_diag*/) {
#ifndef _MSC_VER
    throw cling::CompilationException(reason);
#endif
  }
} // end namespace cling
<|endoftext|>


<commit_before>//===-- Local.cpp - Functions to perform local transformations ------------===//
//
//                     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 family of functions perform various local transformations to the
// program.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Local constant propagation...
//

/// doConstantPropagation - If an instruction references constants, try to fold
/// them together...
///
bool llvm::doConstantPropagation(BasicBlock::iterator &II) {
  if (Constant *C = ConstantFoldInstruction(II)) {
    // Replaces all of the uses of a variable with uses of the constant.
    II->replaceAllUsesWith(C);

    // Remove the instruction from the basic block...
    II = II->getParent()->getInstList().erase(II);
    return true;
  }

  return false;
}

/// ConstantFoldInstruction - Attempt to constant fold the specified
/// instruction.  If successful, the constant result is returned, if not, null
/// is returned.  Note that this function can only fail when attempting to fold
/// instructions like loads and stores, which have no constant expression form.
///
Constant *llvm::ConstantFoldInstruction(Instruction *I) {
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    if (PN->getNumIncomingValues() == 0)
      return Constant::getNullValue(PN->getType());

    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
    if (Result == 0) return 0;

    // Handle PHI nodes specially here...
    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
      if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
        return 0;   // Not all the same incoming constants...

    // If we reach here, all incoming values are the same constant.
    return Result;
  } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
    if (Function *F = CI->getCalledFunction())
      if (canConstantFoldCallTo(F)) {
        std::vector<Constant*> Args;
        for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
          if (Constant *Op = dyn_cast<Constant>(CI->getOperand(i)))
            Args.push_back(Op);
          else
            return 0;
        return ConstantFoldCall(F, Args);
      }
    return 0;
  }

  Constant *Op0 = 0, *Op1 = 0;
  switch (I->getNumOperands()) {
  default:
  case 2:
    Op1 = dyn_cast<Constant>(I->getOperand(1));
    if (Op1 == 0) return 0;        // Not a constant?, can't fold
  case 1:
    Op0 = dyn_cast<Constant>(I->getOperand(0));
    if (Op0 == 0) return 0;        // Not a constant?, can't fold
    break;
  case 0: return 0;
  }

  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
    return ConstantExpr::get(I->getOpcode(), Op0, Op1);

  switch (I->getOpcode()) {
  default: return 0;
  case Instruction::Cast:
    return ConstantExpr::getCast(Op0, I->getType());
  case Instruction::Select:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getSelect(Op0, Op1, Op2);
    return 0;
  case Instruction::ExtractElement:
    return ConstantExpr::getExtractElement(Op0, Op1);
  case Instruction::InsertElement:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getInsertElement(Op0, Op1, Op2);
    return 0;
  case Instruction::ShuffleVector:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
    return 0;
  case Instruction::GetElementPtr:
    std::vector<Constant*> IdxList;
    IdxList.reserve(I->getNumOperands()-1);
    if (Op1) IdxList.push_back(Op1);
    for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
      if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
        IdxList.push_back(C);
      else
        return 0;  // Non-constant operand
    return ConstantExpr::getGetElementPtr(Op0, IdxList);
  }
}

// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
//
bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
  TerminatorInst *T = BB->getTerminator();

  // Branch - See if we are conditional jumping on constant
  if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
    if (BI->isUnconditional()) return false;  // Can't optimize uncond branch
    BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
    BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));

    if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
      // Are we branching on constant?
      // YES.  Change to unconditional branch...
      BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
      BasicBlock *OldDest     = Cond->getValue() ? Dest2 : Dest1;

      //cerr << "Function: " << T->getParent()->getParent()
      //     << "\nRemoving branch from " << T->getParent()
      //     << "\n\nTo: " << OldDest << endl;

      // Let the basic block know that we are letting go of it.  Based on this,
      // it will adjust it's PHI nodes.
      assert(BI->getParent() && "Terminator not inserted in block!");
      OldDest->removePredecessor(BI->getParent());

      // Set the unconditional destination, and change the insn to be an
      // unconditional branch.
      BI->setUnconditionalDest(Destination);
      return true;
    } else if (Dest2 == Dest1) {       // Conditional branch to same location?
      // This branch matches something like this:
      //     br bool %cond, label %Dest, label %Dest
      // and changes it into:  br label %Dest

      // Let the basic block know that we are letting go of one copy of it.
      assert(BI->getParent() && "Terminator not inserted in block!");
      Dest1->removePredecessor(BI->getParent());

      // Change a conditional branch to unconditional.
      BI->setUnconditionalDest(Dest1);
      return true;
    }
  } else if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
    // If we are switching on a constant, we can convert the switch into a
    // single branch instruction!
    ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
    BasicBlock *TheOnlyDest = SI->getSuccessor(0);  // The default dest
    BasicBlock *DefaultDest = TheOnlyDest;
    assert(TheOnlyDest == SI->getDefaultDest() &&
           "Default destination is not successor #0?");

    // Figure out which case it goes to...
    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
      // Found case matching a constant operand?
      if (SI->getSuccessorValue(i) == CI) {
        TheOnlyDest = SI->getSuccessor(i);
        break;
      }

      // Check to see if this branch is going to the same place as the default
      // dest.  If so, eliminate it as an explicit compare.
      if (SI->getSuccessor(i) == DefaultDest) {
        // Remove this entry...
        DefaultDest->removePredecessor(SI->getParent());
        SI->removeCase(i);
        --i; --e;  // Don't skip an entry...
        continue;
      }

      // Otherwise, check to see if the switch only branches to one destination.
      // We do this by reseting "TheOnlyDest" to null when we find two non-equal
      // destinations.
      if (SI->getSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
    }

    if (CI && !TheOnlyDest) {
      // Branching on a constant, but not any of the cases, go to the default
      // successor.
      TheOnlyDest = SI->getDefaultDest();
    }

    // If we found a single destination that we can fold the switch into, do so
    // now.
    if (TheOnlyDest) {
      // Insert the new branch..
      new BranchInst(TheOnlyDest, SI);
      BasicBlock *BB = SI->getParent();

      // Remove entries from PHI nodes which we no longer branch to...
      for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
        // Found case matching a constant operand?
        BasicBlock *Succ = SI->getSuccessor(i);
        if (Succ == TheOnlyDest)
          TheOnlyDest = 0;  // Don't modify the first branch to TheOnlyDest
        else
          Succ->removePredecessor(BB);
      }

      // Delete the old switch...
      BB->getInstList().erase(SI);
      return true;
    } else if (SI->getNumSuccessors() == 2) {
      // Otherwise, we can fold this switch into a conditional branch
      // instruction if it has only one non-default destination.
      Value *Cond = new SetCondInst(Instruction::SetEQ, SI->getCondition(),
                                    SI->getSuccessorValue(1), "cond", SI);
      // Insert the new branch...
      new BranchInst(SI->getSuccessor(1), SI->getSuccessor(0), Cond, SI);

      // Delete the old switch...
      SI->getParent()->getInstList().erase(SI);
      return true;
    }
  }
  return false;
}

/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
/// constant expression, or null if something is funny and we can't decide.
Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C,
                                                       ConstantExpr *CE) {
  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
    return 0;  // Do not allow stepping over the value!

  // Loop over all of the operands, tracking down which value we are
  // addressing...
  gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
  for (++I; I != E; ++I)
    if (const StructType *STy = dyn_cast<StructType>(*I)) {
      ConstantUInt *CU = cast<ConstantUInt>(I.getOperand());
      assert(CU->getValue() < STy->getNumElements() &&
             "Struct index out of range!");
      unsigned El = (unsigned)CU->getValue();
      if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
        C = CS->getOperand(El);
      } else if (isa<ConstantAggregateZero>(C)) {
        C = Constant::getNullValue(STy->getElementType(El));
      } else if (isa<UndefValue>(C)) {
        C = UndefValue::get(STy->getElementType(El));
      } else {
        return 0;
      }
    } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
      if (const ArrayType *ATy = dyn_cast<ArrayType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= ATy->getNumElements())
          C = UndefValue::get(ATy->getElementType());
        if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
          C = CA->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(ATy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(ATy->getElementType());
        else
          return 0;
      } else if (const PackedType *PTy = dyn_cast<PackedType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= PTy->getNumElements())
          C = UndefValue::get(PTy->getElementType());
        if (ConstantPacked *CP = dyn_cast<ConstantPacked>(C))
          C = CP->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(PTy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(PTy->getElementType());
        else
          return 0;
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  return C;
}

//===----------------------------------------------------------------------===//
//  Local dead code elimination...
//

bool llvm::isInstructionTriviallyDead(Instruction *I) {
  if (!I->use_empty() || isa<TerminatorInst>(I)) return false;

  if (!I->mayWriteToMemory()) return true;

  if (CallInst *CI = dyn_cast<CallInst>(I))
    if (Function *F = CI->getCalledFunction()) {
      unsigned IntrinsicID = F->getIntrinsicID();
#define GET_SIDE_EFFECT_INFO
#include "llvm/Intrinsics.gen"
#undef GET_SIDE_EFFECT_INFO
    }
  return false;
}

// dceInstruction - Inspect the instruction at *BBI and figure out if it's
// [trivially] dead.  If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
bool llvm::dceInstruction(BasicBlock::iterator &BBI) {
  // Look for un"used" definitions...
  if (isInstructionTriviallyDead(BBI)) {
    BBI = BBI->getParent()->getInstList().erase(BBI);   // Bye bye
    return true;
  }
  return false;
}
<commit_msg>Revert a patch that is unsafe, due to out of range array accesses in inner array scopes possibly accessing valid memory in outer subscripts.<commit_after>//===-- Local.cpp - Functions to perform local transformations ------------===//
//
//                     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 family of functions perform various local transformations to the
// program.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Local constant propagation...
//

/// doConstantPropagation - If an instruction references constants, try to fold
/// them together...
///
bool llvm::doConstantPropagation(BasicBlock::iterator &II) {
  if (Constant *C = ConstantFoldInstruction(II)) {
    // Replaces all of the uses of a variable with uses of the constant.
    II->replaceAllUsesWith(C);

    // Remove the instruction from the basic block...
    II = II->getParent()->getInstList().erase(II);
    return true;
  }

  return false;
}

/// ConstantFoldInstruction - Attempt to constant fold the specified
/// instruction.  If successful, the constant result is returned, if not, null
/// is returned.  Note that this function can only fail when attempting to fold
/// instructions like loads and stores, which have no constant expression form.
///
Constant *llvm::ConstantFoldInstruction(Instruction *I) {
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    if (PN->getNumIncomingValues() == 0)
      return Constant::getNullValue(PN->getType());

    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
    if (Result == 0) return 0;

    // Handle PHI nodes specially here...
    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
      if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
        return 0;   // Not all the same incoming constants...

    // If we reach here, all incoming values are the same constant.
    return Result;
  } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
    if (Function *F = CI->getCalledFunction())
      if (canConstantFoldCallTo(F)) {
        std::vector<Constant*> Args;
        for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
          if (Constant *Op = dyn_cast<Constant>(CI->getOperand(i)))
            Args.push_back(Op);
          else
            return 0;
        return ConstantFoldCall(F, Args);
      }
    return 0;
  }

  Constant *Op0 = 0, *Op1 = 0;
  switch (I->getNumOperands()) {
  default:
  case 2:
    Op1 = dyn_cast<Constant>(I->getOperand(1));
    if (Op1 == 0) return 0;        // Not a constant?, can't fold
  case 1:
    Op0 = dyn_cast<Constant>(I->getOperand(0));
    if (Op0 == 0) return 0;        // Not a constant?, can't fold
    break;
  case 0: return 0;
  }

  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
    return ConstantExpr::get(I->getOpcode(), Op0, Op1);

  switch (I->getOpcode()) {
  default: return 0;
  case Instruction::Cast:
    return ConstantExpr::getCast(Op0, I->getType());
  case Instruction::Select:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getSelect(Op0, Op1, Op2);
    return 0;
  case Instruction::ExtractElement:
    return ConstantExpr::getExtractElement(Op0, Op1);
  case Instruction::InsertElement:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getInsertElement(Op0, Op1, Op2);
    return 0;
  case Instruction::ShuffleVector:
    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
      return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
    return 0;
  case Instruction::GetElementPtr:
    std::vector<Constant*> IdxList;
    IdxList.reserve(I->getNumOperands()-1);
    if (Op1) IdxList.push_back(Op1);
    for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
      if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
        IdxList.push_back(C);
      else
        return 0;  // Non-constant operand
    return ConstantExpr::getGetElementPtr(Op0, IdxList);
  }
}

// ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant
// destination.
//
bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
  TerminatorInst *T = BB->getTerminator();

  // Branch - See if we are conditional jumping on constant
  if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
    if (BI->isUnconditional()) return false;  // Can't optimize uncond branch
    BasicBlock *Dest1 = cast<BasicBlock>(BI->getOperand(0));
    BasicBlock *Dest2 = cast<BasicBlock>(BI->getOperand(1));

    if (ConstantBool *Cond = dyn_cast<ConstantBool>(BI->getCondition())) {
      // Are we branching on constant?
      // YES.  Change to unconditional branch...
      BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
      BasicBlock *OldDest     = Cond->getValue() ? Dest2 : Dest1;

      //cerr << "Function: " << T->getParent()->getParent()
      //     << "\nRemoving branch from " << T->getParent()
      //     << "\n\nTo: " << OldDest << endl;

      // Let the basic block know that we are letting go of it.  Based on this,
      // it will adjust it's PHI nodes.
      assert(BI->getParent() && "Terminator not inserted in block!");
      OldDest->removePredecessor(BI->getParent());

      // Set the unconditional destination, and change the insn to be an
      // unconditional branch.
      BI->setUnconditionalDest(Destination);
      return true;
    } else if (Dest2 == Dest1) {       // Conditional branch to same location?
      // This branch matches something like this:
      //     br bool %cond, label %Dest, label %Dest
      // and changes it into:  br label %Dest

      // Let the basic block know that we are letting go of one copy of it.
      assert(BI->getParent() && "Terminator not inserted in block!");
      Dest1->removePredecessor(BI->getParent());

      // Change a conditional branch to unconditional.
      BI->setUnconditionalDest(Dest1);
      return true;
    }
  } else if (SwitchInst *SI = dyn_cast<SwitchInst>(T)) {
    // If we are switching on a constant, we can convert the switch into a
    // single branch instruction!
    ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
    BasicBlock *TheOnlyDest = SI->getSuccessor(0);  // The default dest
    BasicBlock *DefaultDest = TheOnlyDest;
    assert(TheOnlyDest == SI->getDefaultDest() &&
           "Default destination is not successor #0?");

    // Figure out which case it goes to...
    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
      // Found case matching a constant operand?
      if (SI->getSuccessorValue(i) == CI) {
        TheOnlyDest = SI->getSuccessor(i);
        break;
      }

      // Check to see if this branch is going to the same place as the default
      // dest.  If so, eliminate it as an explicit compare.
      if (SI->getSuccessor(i) == DefaultDest) {
        // Remove this entry...
        DefaultDest->removePredecessor(SI->getParent());
        SI->removeCase(i);
        --i; --e;  // Don't skip an entry...
        continue;
      }

      // Otherwise, check to see if the switch only branches to one destination.
      // We do this by reseting "TheOnlyDest" to null when we find two non-equal
      // destinations.
      if (SI->getSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
    }

    if (CI && !TheOnlyDest) {
      // Branching on a constant, but not any of the cases, go to the default
      // successor.
      TheOnlyDest = SI->getDefaultDest();
    }

    // If we found a single destination that we can fold the switch into, do so
    // now.
    if (TheOnlyDest) {
      // Insert the new branch..
      new BranchInst(TheOnlyDest, SI);
      BasicBlock *BB = SI->getParent();

      // Remove entries from PHI nodes which we no longer branch to...
      for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
        // Found case matching a constant operand?
        BasicBlock *Succ = SI->getSuccessor(i);
        if (Succ == TheOnlyDest)
          TheOnlyDest = 0;  // Don't modify the first branch to TheOnlyDest
        else
          Succ->removePredecessor(BB);
      }

      // Delete the old switch...
      BB->getInstList().erase(SI);
      return true;
    } else if (SI->getNumSuccessors() == 2) {
      // Otherwise, we can fold this switch into a conditional branch
      // instruction if it has only one non-default destination.
      Value *Cond = new SetCondInst(Instruction::SetEQ, SI->getCondition(),
                                    SI->getSuccessorValue(1), "cond", SI);
      // Insert the new branch...
      new BranchInst(SI->getSuccessor(1), SI->getSuccessor(0), Cond, SI);

      // Delete the old switch...
      SI->getParent()->getInstList().erase(SI);
      return true;
    }
  }
  return false;
}

/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
/// constant expression, or null if something is funny and we can't decide.
Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C,
                                                       ConstantExpr *CE) {
  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
    return 0;  // Do not allow stepping over the value!

  // Loop over all of the operands, tracking down which value we are
  // addressing...
  gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
  for (++I; I != E; ++I)
    if (const StructType *STy = dyn_cast<StructType>(*I)) {
      ConstantUInt *CU = cast<ConstantUInt>(I.getOperand());
      assert(CU->getValue() < STy->getNumElements() &&
             "Struct index out of range!");
      unsigned El = (unsigned)CU->getValue();
      if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
        C = CS->getOperand(El);
      } else if (isa<ConstantAggregateZero>(C)) {
        C = Constant::getNullValue(STy->getElementType(El));
      } else if (isa<UndefValue>(C)) {
        C = UndefValue::get(STy->getElementType(El));
      } else {
        return 0;
      }
    } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
      if (const ArrayType *ATy = dyn_cast<ArrayType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= ATy->getNumElements())
         return 0;
        if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
          C = CA->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(ATy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(ATy->getElementType());
        else
          return 0;
      } else if (const PackedType *PTy = dyn_cast<PackedType>(*I)) {
        if ((uint64_t)CI->getRawValue() >= PTy->getNumElements())
          return 0;
        if (ConstantPacked *CP = dyn_cast<ConstantPacked>(C))
          C = CP->getOperand((unsigned)CI->getRawValue());
        else if (isa<ConstantAggregateZero>(C))
          C = Constant::getNullValue(PTy->getElementType());
        else if (isa<UndefValue>(C))
          C = UndefValue::get(PTy->getElementType());
        else
          return 0;
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  return C;
}

//===----------------------------------------------------------------------===//
//  Local dead code elimination...
//

bool llvm::isInstructionTriviallyDead(Instruction *I) {
  if (!I->use_empty() || isa<TerminatorInst>(I)) return false;

  if (!I->mayWriteToMemory()) return true;

  if (CallInst *CI = dyn_cast<CallInst>(I))
    if (Function *F = CI->getCalledFunction()) {
      unsigned IntrinsicID = F->getIntrinsicID();
#define GET_SIDE_EFFECT_INFO
#include "llvm/Intrinsics.gen"
#undef GET_SIDE_EFFECT_INFO
    }
  return false;
}

// dceInstruction - Inspect the instruction at *BBI and figure out if it's
// [trivially] dead.  If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
bool llvm::dceInstruction(BasicBlock::iterator &BBI) {
  // Look for un"used" definitions...
  if (isInstructionTriviallyDead(BBI)) {
    BBI = BBI->getParent()->getInstList().erase(BBI);   // Bye bye
    return true;
  }
  return false;
}
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_WALK_HH_INCLUDED
#define DUNE_STUFF_WALK_HH_INCLUDED

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#include <dune/common/deprecated.hh>
#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/math.hh>
#include <dune/stuff/common/misc.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/grid/common/geometry.hh>
#include <dune/stuff/aliases.hh>

#include <vector>
#include <boost/format.hpp>

namespace Dune {
namespace Stuff {
namespace Grid {

/** \brief Useful dummy functor if you don't have anything to do on entities/intersections
 **/
struct GridWalkDummyFunctor {
  GridWalkDummyFunctor(){}

  template < class Entity >
  void operator() ( const Entity&, const int) const
  {}
  template < class Entity, class Intersection >
  void operator() ( const Entity&, const Intersection&) const
  {}
};

namespace {
  /** \brief global \ref GridWalkDummyFunctor instance
   **/
  const GridWalkDummyFunctor gridWalkDummyFunctor;
}

/** \brief applies Functors on each \ref Entity/\ref Intersection of a given \ref GridView
 *  \todo allow stacking of functor to save gridwalks?
 *  \tparam GridViewImp any \ref GridView interface compliant type
 *  \tparam codim determines the codim of the Entities that are iterated on
 **/
template < class GridViewImp, int codim = 0 >
class GridWalk {
  typedef Dune::GridView<typename GridViewImp::Traits> GridViewType;
public:
  GridWalk ( const GridViewType& gp )
    : gridView_( gp )
  {}

  /** \param entityFunctor is applied on all codim 0 entities presented by \var gridView_
   *  \param intersectionFunctor is applied on all Intersections of all codim 0 entities
   *        presented by \var gridView_
   *  \note only instantiable for codim == 0
   */
  template < class EntityFunctor, class IntersectionFunctor >
  void operator () ( EntityFunctor& entityFunctor, IntersectionFunctor& intersectionFunctor ) const
  {
    static_assert( codim == 0, "walking intersections is only possible for codim 0 entities" );
    for (const auto& entity : DSC::entityRange(gridView_)) {
      const int entityIndex = gridView_.indexSet().index(entity);
      entityFunctor( entity, entityIndex);
      for (const auto& intersection : DSC::intersectionRange(gridView_, entity)) {
        intersectionFunctor( entity, intersection);
      }
    }
  }

  /** \param entityFunctor is applied on all codim entities presented by \var gridView_
   *  \note only instantiable for codim < GridView::dimension
   */
  template < class EntityFunctor >
  void operator () ( EntityFunctor& entityFunctor ) const
  {
    static_assert( codim <= GridViewType::dimension, "codim too high to walk" );
    for (const auto& entity : DSC::entityRange(gridView_)) {
      const int entityIndex = gridView_.indexSet().index(entity);
      entityFunctor( entity, entityIndex);
    }
  }

private:
  const GridViewType& gridView_;
};

//!
template <class ViewImp, int codim = 0>
GridWalk< Dune::GridView<ViewImp>, codim > make_gridwalk(const Dune::GridView<ViewImp>& view) {
    return GridWalk< Dune::GridView<ViewImp>, codim >(view);
}

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // ifndef DUNE_STUFF_WALK_HH_INCLUDED
<commit_msg>[grid.walk] update include guard<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_GRID_WALK_HH
#define DUNE_STUFF_GRID_WALK_HH

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/fvector.hh>
#include <dune/stuff/common/reenable_warnings.hh>
#include <dune/common/deprecated.hh>
#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/math.hh>
#include <dune/stuff/common/misc.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/grid/common/geometry.hh>
#include <dune/stuff/aliases.hh>

#include <vector>
#include <boost/format.hpp>

namespace Dune {
namespace Stuff {
namespace Grid {

/** \brief Useful dummy functor if you don't have anything to do on entities/intersections
 **/
struct GridWalkDummyFunctor {
  GridWalkDummyFunctor(){}

  template < class Entity >
  void operator() ( const Entity&, const int) const
  {}
  template < class Entity, class Intersection >
  void operator() ( const Entity&, const Intersection&) const
  {}
};

namespace {
  /** \brief global \ref GridWalkDummyFunctor instance
   **/
  const GridWalkDummyFunctor gridWalkDummyFunctor;
}

/** \brief applies Functors on each \ref Entity/\ref Intersection of a given \ref GridView
 *  \todo allow stacking of functor to save gridwalks?
 *  \tparam GridViewImp any \ref GridView interface compliant type
 *  \tparam codim determines the codim of the Entities that are iterated on
 **/
template < class GridViewImp, int codim = 0 >
class GridWalk {
  typedef Dune::GridView<typename GridViewImp::Traits> GridViewType;
public:
  GridWalk ( const GridViewType& gp )
    : gridView_( gp )
  {}

  /** \param entityFunctor is applied on all codim 0 entities presented by \var gridView_
   *  \param intersectionFunctor is applied on all Intersections of all codim 0 entities
   *        presented by \var gridView_
   *  \note only instantiable for codim == 0
   */
  template < class EntityFunctor, class IntersectionFunctor >
  void operator () ( EntityFunctor& entityFunctor, IntersectionFunctor& intersectionFunctor ) const
  {
    static_assert( codim == 0, "walking intersections is only possible for codim 0 entities" );
    for (const auto& entity : DSC::entityRange(gridView_)) {
      const int entityIndex = gridView_.indexSet().index(entity);
      entityFunctor( entity, entityIndex);
      for (const auto& intersection : DSC::intersectionRange(gridView_, entity)) {
        intersectionFunctor( entity, intersection);
      }
    }
  }

  /** \param entityFunctor is applied on all codim entities presented by \var gridView_
   *  \note only instantiable for codim < GridView::dimension
   */
  template < class EntityFunctor >
  void operator () ( EntityFunctor& entityFunctor ) const
  {
    static_assert( codim <= GridViewType::dimension, "codim too high to walk" );
    for (const auto& entity : DSC::entityRange(gridView_)) {
      const int entityIndex = gridView_.indexSet().index(entity);
      entityFunctor( entity, entityIndex);
    }
  }

private:
  const GridViewType& gridView_;
};

//!
template <class ViewImp, int codim = 0>
GridWalk< Dune::GridView<ViewImp>, codim > make_gridwalk(const Dune::GridView<ViewImp>& view) {
    return GridWalk< Dune::GridView<ViewImp>, codim >(view);
}

} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_GRID_WALK_HH
<|endoftext|>


<commit_before>/*
 * Author: Ivan De Cesaris <ivan.de.cesaris@intel.com>
 * Copyright (c) 2015 - 2016 Intel Corporation.
 *
 * 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.
 */

/**
 * Demonstrate how to read a digital value from an input pin using the MRAA
 * library.
 * Suitable ones in the Grove Starter Kit are the Button and Touch Sensor,
 * connected to digital pin 4 (Grove Base Shield Port D4).
 * For the connection to the Grosse Tête connect the Pin 4 (Grove Base Shield)
 * to the Pin 1 on Breakout#1 (Grosse Tête). Futhermore, connect the 3v3 Pin and
 * GND Pin (Grove Base Shield)  to Pin 40 on Breakout#1 and Pin 1 on Breakout#2
 * (Grosse Tête).
 */

#include <mraa.hpp>

#include <iostream>
#include <unistd.h>

int main()
{
	// check that we are running on Galileo or Edison
	mraa::Platform platform = mraa::getPlatformType();
	if ((platform != mraa::INTEL_GALILEO_GEN1) &&
			(platform != mraa::INTEL_GALILEO_GEN2) &&
			(platform != mraa::INTEL_EDISON_FAB_C) &&
			 (platform != mraa::INTEL_JOULE_EXPANSION)) {
		std::cerr << "Unsupported platform, exiting" << std::endl;
		return mraa::ERROR_INVALID_PLATFORM;
	}

	// create a GPIO object from MRAA using pin 4
	mraa::Gpio* d_pin = new mraa::Gpio(4);
	if (d_pin == NULL) {
		std::cerr << "Can't create mraa::Gpio object, exiting" << std::endl;
		return mraa::ERROR_UNSPECIFIED;
	}

	// set the pin as input
	if (d_pin->dir(mraa::DIR_IN) != mraa::SUCCESS) {
		std::cerr << "Can't set digital pin as input, exiting" << std::endl;
		return mraa::ERROR_UNSPECIFIED;
	}

	// loop forever printing the digital input value every second
	for (;;) {
		int pin_value = d_pin->read();
		std::cout << "value " << pin_value << std::endl;
		sleep(1);
	}

	return mraa::SUCCESS;
}
<commit_msg>Fix Reference to Intel Joule<commit_after>/*
 * Author: Ivan De Cesaris <ivan.de.cesaris@intel.com>
 * Copyright (c) 2015 - 2016 Intel Corporation.
 *
 * 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.
 */

/**
 * Demonstrate how to read a digital value from an input pin using the MRAA
 * library.
 * Suitable ones in the Grove Starter Kit are the Button and Touch Sensor,
 * connected to digital pin 4 (Grove Base Shield Port D4).
 * For the connection to the Intel Joule connect the Pin 4 (Grove Base Shield)
 * to the Pin 1 on Breakout#1 (Intel Joule). Futhermore, connect the 3v3 Pin and
 * GND Pin (Grove Base Shield)  to Pin 40 on Breakout#1 and Pin 1 on Breakout#2
 * (Intel Joule).
 */

#include <mraa.hpp>

#include <iostream>
#include <unistd.h>

int main()
{
	// check that we are running on Galileo or Edison
	mraa::Platform platform = mraa::getPlatformType();
	if ((platform != mraa::INTEL_GALILEO_GEN1) &&
			(platform != mraa::INTEL_GALILEO_GEN2) &&
			(platform != mraa::INTEL_EDISON_FAB_C) &&
			 (platform != mraa::INTEL_JOULE_EXPANSION)) {
		std::cerr << "Unsupported platform, exiting" << std::endl;
		return mraa::ERROR_INVALID_PLATFORM;
	}

	// create a GPIO object from MRAA using pin 4
	mraa::Gpio* d_pin = new mraa::Gpio(4);
	if (d_pin == NULL) {
		std::cerr << "Can't create mraa::Gpio object, exiting" << std::endl;
		return mraa::ERROR_UNSPECIFIED;
	}

	// set the pin as input
	if (d_pin->dir(mraa::DIR_IN) != mraa::SUCCESS) {
		std::cerr << "Can't set digital pin as input, exiting" << std::endl;
		return mraa::ERROR_UNSPECIFIED;
	}

	// loop forever printing the digital input value every second
	for (;;) {
		int pin_value = d_pin->read();
		std::cout << "value " << pin_value << std::endl;
		sleep(1);
	}

	return mraa::SUCCESS;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2019 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/prediction/common/message_process.h"

#include <algorithm>
#include <vector>

#include "cyber/common/file.h"
#include "cyber/record/record_reader.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/prediction/common/feature_output.h"
#include "modules/prediction/common/junction_analyzer.h"
#include "modules/prediction/common/prediction_gflags.h"
#include "modules/prediction/common/prediction_system_gflags.h"
#include "modules/prediction/common/validation_checker.h"
#include "modules/prediction/evaluator/evaluator_manager.h"
#include "modules/prediction/predictor/predictor_manager.h"
#include "modules/prediction/proto/offline_features.pb.h"
#include "modules/prediction/scenario/prioritization/obstacles_prioritizer.h"
#include "modules/prediction/scenario/right_of_way/right_of_way.h"
#include "modules/prediction/scenario/scenario_manager.h"
#include "modules/prediction/util/data_extraction.h"

namespace apollo {
namespace prediction {

using apollo::common::adapter::AdapterConfig;
using apollo::localization::LocalizationEstimate;
using apollo::perception::PerceptionObstacle;
using apollo::perception::PerceptionObstacles;
using apollo::planning::ADCTrajectory;
using cyber::record::RecordMessage;
using cyber::record::RecordReader;

bool MessageProcess::Init() {
  // Load prediction conf
  PredictionConf prediction_conf;
  if (!cyber::common::GetProtoFromFile(FLAGS_prediction_conf_file,
                                       &prediction_conf)) {
    AERROR << "Unable to load prediction conf file: "
           << FLAGS_prediction_conf_file;
    return false;
  }
  ADEBUG << "Prediction config file is loaded into: "
         << prediction_conf.ShortDebugString();

  common::adapter::AdapterManagerConfig adapter_conf;
  if (!cyber::common::GetProtoFromFile(FLAGS_prediction_adapter_config_filename,
                                       &adapter_conf)) {
    AERROR << "Unable to load adapter conf file: "
           << FLAGS_prediction_adapter_config_filename;
    return false;
  }
  ADEBUG << "Adapter config file is loaded into: "
         << adapter_conf.ShortDebugString();

  // Initialization of all managers
  ContainerManager::Instance()->Init(adapter_conf);
  EvaluatorManager::Instance()->Init(prediction_conf);
  PredictorManager::Instance()->Init(prediction_conf);

  if (!FLAGS_use_navigation_mode && !PredictionMap::Ready()) {
    AERROR << "Map cannot be loaded.";
    return false;
  }

  return true;
}

void MessageProcess::OnPerception(
    const perception::PerceptionObstacles& perception_obstacles,
    PredictionObstacles* const prediction_obstacles) {
  ADEBUG << "Received a perception message ["
         << perception_obstacles.ShortDebugString() << "].";

  // Get obstacles_container
  auto ptr_obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
  CHECK_NOTNULL(ptr_obstacles_container);

  // Get pose_container
  auto ptr_ego_pose_container =
      ContainerManager::Instance()->GetContainer<PoseContainer>(
          AdapterConfig::LOCALIZATION);
  CHECK_NOTNULL(ptr_ego_pose_container);

  // Get adc_trajectory_container
  auto ptr_ego_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
  CHECK_NOTNULL(ptr_ego_trajectory_container);

  // Insert ADC into the obstacle_container.
  const PerceptionObstacle* ptr_ego_vehicle =
      ptr_ego_pose_container->ToPerceptionObstacle();
  if (ptr_ego_vehicle != nullptr) {
    ptr_obstacles_container->InsertPerceptionObstacle(
        *ptr_ego_vehicle, ptr_ego_vehicle->timestamp());
    double x = ptr_ego_vehicle->position().x();
    double y = ptr_ego_vehicle->position().y();
    ADEBUG << "Get ADC position [" << std::fixed << std::setprecision(6) << x
           << ", " << std::fixed << std::setprecision(6) << y << "].";
    ptr_ego_trajectory_container->SetPosition({x, y});
  }

  // Insert perception_obstacles
  ptr_obstacles_container->Insert(perception_obstacles);

  // Ignore some obstacles
  ObstaclesPrioritizer::Instance()->AssignIgnoreLevel();

  // Scenario analysis
  ScenarioManager::Instance()->Run();

  // Build junction feature for the obstacles in junction
  const Scenario& scenario = ScenarioManager::Instance()->scenario();
  if (scenario.type() == Scenario::JUNCTION && scenario.has_junction_id()) {
    JunctionAnalyzer::Init(scenario.junction_id());
    ptr_obstacles_container->BuildJunctionFeature();
  }

  // Build lane graph
  ptr_obstacles_container->BuildLaneGraph();

  // Assign CautionLevel for obstacles
  ObstaclesPrioritizer::Instance()->AssignCautionLevel();

  // Analyze RightOfWay for the caution obstacles
  RightOfWay::Analyze();

  // Insert features to FeatureOutput for offline_mode
  if (FLAGS_prediction_offline_mode == 1) {
    for (const int id :
         ptr_obstacles_container->curr_frame_movable_obstacle_ids()) {
      Obstacle* obstacle_ptr = ptr_obstacles_container->GetObstacle(id);
      if (obstacle_ptr == nullptr) {
        AERROR << "Null obstacle found.";
        continue;
      } else if (!obstacle_ptr->latest_feature().IsInitialized()) {
        AERROR << "Obstacle [" << id << "] has no latest feature.";
        continue;
      }
      *obstacle_ptr->mutable_latest_feature()->mutable_adc_trajectory_point() =
          ptr_ego_trajectory_container->adc_trajectory().trajectory_point();
      FeatureOutput::InsertFeatureProto(obstacle_ptr->latest_feature());
      ADEBUG << "Insert feature into feature output";
    }
    // Not doing evaluation on offline mode
    return;
  }

  // Make evaluations
  EvaluatorManager::Instance()->Run();

  // Make predictions
  PredictorManager::Instance()->Run();

  // Get predicted obstacles
  *prediction_obstacles = PredictorManager::Instance()->prediction_obstacles();
}

void MessageProcess::OnLocalization(
    const localization::LocalizationEstimate& localization) {
  auto ptr_ego_pose_container =
      ContainerManager::Instance()->GetContainer<PoseContainer>(
          AdapterConfig::LOCALIZATION);
  CHECK(ptr_ego_pose_container != nullptr);
  ptr_ego_pose_container->Insert(localization);

  ADEBUG << "Received a localization message ["
         << localization.ShortDebugString() << "].";
}

void MessageProcess::OnPlanning(const planning::ADCTrajectory& adc_trajectory) {
  auto ptr_ego_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
  CHECK(ptr_ego_trajectory_container != nullptr);
  ptr_ego_trajectory_container->Insert(adc_trajectory);

  ADEBUG << "Received a planning message [" << adc_trajectory.ShortDebugString()
         << "].";
}

void MessageProcess::ProcessOfflineData(const std::string& record_filename) {
  RecordReader reader(record_filename);
  RecordMessage message;
  while (reader.ReadMessage(&message)) {
    if (message.channel_name == FLAGS_perception_obstacle_topic) {
      PerceptionObstacles perception_obstacles;
      if (perception_obstacles.ParseFromString(message.content)) {
        PredictionObstacles prediction_obstacles;
        OnPerception(perception_obstacles, &prediction_obstacles);
      }
    } else if (message.channel_name == FLAGS_localization_topic) {
      LocalizationEstimate localization;
      if (localization.ParseFromString(message.content)) {
        OnLocalization(localization);
      }
    } else if (message.channel_name == FLAGS_planning_trajectory_topic) {
      ADCTrajectory adc_trajectory;
      if (adc_trajectory.ParseFromString(message.content)) {
        OnPlanning(adc_trajectory);
      }
    }
  }
}

}  // namespace prediction
}  // namespace apollo
<commit_msg>Prediction: trival logic adjudgement<commit_after>/******************************************************************************
 * Copyright 2019 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/prediction/common/message_process.h"

#include <algorithm>
#include <vector>

#include "cyber/common/file.h"
#include "cyber/record/record_reader.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/prediction/common/feature_output.h"
#include "modules/prediction/common/junction_analyzer.h"
#include "modules/prediction/common/prediction_gflags.h"
#include "modules/prediction/common/prediction_system_gflags.h"
#include "modules/prediction/common/validation_checker.h"
#include "modules/prediction/evaluator/evaluator_manager.h"
#include "modules/prediction/predictor/predictor_manager.h"
#include "modules/prediction/proto/offline_features.pb.h"
#include "modules/prediction/scenario/prioritization/obstacles_prioritizer.h"
#include "modules/prediction/scenario/right_of_way/right_of_way.h"
#include "modules/prediction/scenario/scenario_manager.h"
#include "modules/prediction/util/data_extraction.h"

namespace apollo {
namespace prediction {

using apollo::common::adapter::AdapterConfig;
using apollo::localization::LocalizationEstimate;
using apollo::perception::PerceptionObstacle;
using apollo::perception::PerceptionObstacles;
using apollo::planning::ADCTrajectory;
using cyber::record::RecordMessage;
using cyber::record::RecordReader;

bool MessageProcess::Init() {
  // Load prediction conf
  PredictionConf prediction_conf;
  if (!cyber::common::GetProtoFromFile(FLAGS_prediction_conf_file,
                                       &prediction_conf)) {
    AERROR << "Unable to load prediction conf file: "
           << FLAGS_prediction_conf_file;
    return false;
  }
  ADEBUG << "Prediction config file is loaded into: "
         << prediction_conf.ShortDebugString();

  common::adapter::AdapterManagerConfig adapter_conf;
  if (!cyber::common::GetProtoFromFile(FLAGS_prediction_adapter_config_filename,
                                       &adapter_conf)) {
    AERROR << "Unable to load adapter conf file: "
           << FLAGS_prediction_adapter_config_filename;
    return false;
  }
  ADEBUG << "Adapter config file is loaded into: "
         << adapter_conf.ShortDebugString();

  // Initialization of all managers
  ContainerManager::Instance()->Init(adapter_conf);
  EvaluatorManager::Instance()->Init(prediction_conf);
  PredictorManager::Instance()->Init(prediction_conf);

  if (!FLAGS_use_navigation_mode && !PredictionMap::Ready()) {
    AERROR << "Map cannot be loaded.";
    return false;
  }

  return true;
}

void MessageProcess::OnPerception(
    const perception::PerceptionObstacles& perception_obstacles,
    PredictionObstacles* const prediction_obstacles) {
  ADEBUG << "Received a perception message ["
         << perception_obstacles.ShortDebugString() << "].";

  // Get obstacles_container
  auto ptr_obstacles_container =
      ContainerManager::Instance()->GetContainer<ObstaclesContainer>(
          AdapterConfig::PERCEPTION_OBSTACLES);
  CHECK_NOTNULL(ptr_obstacles_container);

  // Get pose_container
  auto ptr_ego_pose_container =
      ContainerManager::Instance()->GetContainer<PoseContainer>(
          AdapterConfig::LOCALIZATION);
  CHECK_NOTNULL(ptr_ego_pose_container);

  // Get adc_trajectory_container
  auto ptr_ego_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
  CHECK_NOTNULL(ptr_ego_trajectory_container);

  // Insert ADC into the obstacle_container.
  const PerceptionObstacle* ptr_ego_vehicle =
      ptr_ego_pose_container->ToPerceptionObstacle();
  if (ptr_ego_vehicle != nullptr) {
    ptr_obstacles_container->InsertPerceptionObstacle(
        *ptr_ego_vehicle, ptr_ego_vehicle->timestamp());
    double x = ptr_ego_vehicle->position().x();
    double y = ptr_ego_vehicle->position().y();
    ADEBUG << "Get ADC position [" << std::fixed << std::setprecision(6) << x
           << ", " << std::fixed << std::setprecision(6) << y << "].";
    ptr_ego_trajectory_container->SetPosition({x, y});
  }

  // Insert perception_obstacles
  ptr_obstacles_container->Insert(perception_obstacles);

  // Ignore some obstacles
  ObstaclesPrioritizer::Instance()->AssignIgnoreLevel();

  // Scenario analysis
  ScenarioManager::Instance()->Run();

  // Build junction feature for the obstacles in junction
  const Scenario& scenario = ScenarioManager::Instance()->scenario();
  if (scenario.type() == Scenario::JUNCTION && scenario.has_junction_id()) {
    JunctionAnalyzer::Init(scenario.junction_id());
    ptr_obstacles_container->BuildJunctionFeature();
  }

  // Build lane graph
  ptr_obstacles_container->BuildLaneGraph();

  // Assign CautionLevel for obstacles
  ObstaclesPrioritizer::Instance()->AssignCautionLevel();

  // Analyze RightOfWay for the caution obstacles
  RightOfWay::Analyze();

  // Insert features to FeatureOutput for offline_mode
  if (FLAGS_prediction_offline_mode == 1) {
    for (const int id :
         ptr_obstacles_container->curr_frame_movable_obstacle_ids()) {
      Obstacle* obstacle_ptr = ptr_obstacles_container->GetObstacle(id);
      if (obstacle_ptr == nullptr) {
        AERROR << "Null obstacle found.";
        continue;
      }
      if (!obstacle_ptr->latest_feature().IsInitialized()) {
        AERROR << "Obstacle [" << id << "] has no latest feature.";
        continue;
      }
      *obstacle_ptr->mutable_latest_feature()->mutable_adc_trajectory_point() =
          ptr_ego_trajectory_container->adc_trajectory().trajectory_point();
      FeatureOutput::InsertFeatureProto(obstacle_ptr->latest_feature());
      ADEBUG << "Insert feature into feature output";
    }
    // Not doing evaluation on offline mode
    return;
  }

  // Make evaluations
  EvaluatorManager::Instance()->Run();

  // Make predictions
  PredictorManager::Instance()->Run();

  // Get predicted obstacles
  *prediction_obstacles = PredictorManager::Instance()->prediction_obstacles();
}

void MessageProcess::OnLocalization(
    const localization::LocalizationEstimate& localization) {
  auto ptr_ego_pose_container =
      ContainerManager::Instance()->GetContainer<PoseContainer>(
          AdapterConfig::LOCALIZATION);
  CHECK(ptr_ego_pose_container != nullptr);
  ptr_ego_pose_container->Insert(localization);

  ADEBUG << "Received a localization message ["
         << localization.ShortDebugString() << "].";
}

void MessageProcess::OnPlanning(const planning::ADCTrajectory& adc_trajectory) {
  auto ptr_ego_trajectory_container =
      ContainerManager::Instance()->GetContainer<ADCTrajectoryContainer>(
          AdapterConfig::PLANNING_TRAJECTORY);
  CHECK(ptr_ego_trajectory_container != nullptr);
  ptr_ego_trajectory_container->Insert(adc_trajectory);

  ADEBUG << "Received a planning message [" << adc_trajectory.ShortDebugString()
         << "].";
}

void MessageProcess::ProcessOfflineData(const std::string& record_filename) {
  RecordReader reader(record_filename);
  RecordMessage message;
  while (reader.ReadMessage(&message)) {
    if (message.channel_name == FLAGS_perception_obstacle_topic) {
      PerceptionObstacles perception_obstacles;
      if (perception_obstacles.ParseFromString(message.content)) {
        PredictionObstacles prediction_obstacles;
        OnPerception(perception_obstacles, &prediction_obstacles);
      }
    } else if (message.channel_name == FLAGS_localization_topic) {
      LocalizationEstimate localization;
      if (localization.ParseFromString(message.content)) {
        OnLocalization(localization);
      }
    } else if (message.channel_name == FLAGS_planning_trajectory_topic) {
      ADCTrajectory adc_trajectory;
      if (adc_trajectory.ParseFromString(message.content)) {
        OnPlanning(adc_trajectory);
      }
    }
  }
}

}  // namespace prediction
}  // namespace apollo
<|endoftext|>


<commit_before>//===- ViewOpGraph.cpp - View/write op graphviz graphs --------------------===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================

#include "mlir/Transforms/ViewOpGraph.h"
#include "mlir/IR/Block.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/STLExtras.h"
#include "llvm/Support/CommandLine.h"

static llvm::cl::opt<int> elideIfLarger(
    "print-op-graph-elide-if-larger",
    llvm::cl::desc("Upper limit to emit elements attribute rather than elide"),
    llvm::cl::init(16));

namespace llvm {

// Specialize GraphTraits to treat Block as a graph of Operations as nodes and
// uses as edges.
template <> struct GraphTraits<mlir::Block *> {
  using GraphType = mlir::Block *;
  using NodeRef = mlir::Operation *;

  using ChildIteratorType = mlir::UseIterator;
  static ChildIteratorType child_begin(NodeRef n) {
    return ChildIteratorType(n);
  }
  static ChildIteratorType child_end(NodeRef n) {
    return ChildIteratorType(n, /*end=*/true);
  }

  // Operation's destructor is private so use Operation* instead and use
  // mapped iterator.
  static mlir::Operation *AddressOf(mlir::Operation &op) { return &op; }
  using nodes_iterator =
      mapped_iterator<mlir::Block::iterator, decltype(&AddressOf)>;
  static nodes_iterator nodes_begin(mlir::Block *b) {
    return nodes_iterator(b->begin(), &AddressOf);
  }
  static nodes_iterator nodes_end(mlir::Block *b) {
    return nodes_iterator(b->end(), &AddressOf);
  }
};

// Specialize DOTGraphTraits to produce more readable output.
template <>
struct DOTGraphTraits<mlir::Block *> : public DefaultDOTGraphTraits {
  using DefaultDOTGraphTraits::DefaultDOTGraphTraits;
  static std::string getNodeLabel(mlir::Operation *op, mlir::Block *);
};

std::string DOTGraphTraits<mlir::Block *>::getNodeLabel(mlir::Operation *op,
                                                        mlir::Block *b) {
  // Reuse the print output for the node labels.
  std::string ostr;
  raw_string_ostream os(ostr);
  os << op->getName() << "\n";

  // Print resultant types
  mlir::interleaveComma(op->getResultTypes(), os);
  os << "\n";

  for (auto attr : op->getAttrs()) {
    os << '\n' << attr.first << ": ";
    // Always emit splat attributes.
    if (attr.second.isa<mlir::SplatElementsAttr>()) {
      attr.second.print(os);
      continue;
    }

    // Elide "big" elements attributes.
    auto elements = attr.second.dyn_cast<mlir::ElementsAttr>();
    if (elements && elements.getNumElements() > elideIfLarger) {
      os << std::string(elements.getType().getRank(), '[') << "..."
         << std::string(elements.getType().getRank(), ']') << " : "
         << elements.getType();
      continue;
    }

    // Print all other attributes.
    attr.second.print(os);
  }
  return os.str();
}

} // end namespace llvm

namespace {
// PrintOpPass is simple pass to write graph per function.
// Note: this is a module pass only to avoid interleaving on the same ostream
// due to multi-threading over functions.
struct PrintOpPass : public mlir::ModulePass<PrintOpPass> {
  explicit PrintOpPass(llvm::raw_ostream &os = llvm::errs(),
                       bool short_names = false, const llvm::Twine &title = "")
      : os(os), title(title.str()), short_names(short_names) {}

  std::string getOpName(mlir::Operation &op) {
    auto symbolAttr = op.getAttrOfType<mlir::StringAttr>(
        mlir::SymbolTable::getSymbolAttrName());
    if (symbolAttr)
      return symbolAttr.getValue();
    ++unnamedOpCtr;
    return (op.getName().getStringRef() + llvm::utostr(unnamedOpCtr)).str();
  }

  // Print all the ops in a module.
  void processModule(mlir::ModuleOp module) {
    for (mlir::Operation &op : module) {
      // Modules may actually be nested, recurse on nesting.
      if (auto nestedModule = llvm::dyn_cast<mlir::ModuleOp>(op)) {
        processModule(nestedModule);
        continue;
      }
      auto opName = getOpName(op);
      for (mlir::Region &region : op.getRegions()) {
        for (auto indexed_block : llvm::enumerate(region)) {
          // Suffix block number if there are more than 1 block.
          auto blockName = region.getBlocks().size() == 1
                               ? ""
                               : ("__" + llvm::utostr(indexed_block.index()));
          llvm::WriteGraph(os, &indexed_block.value(), short_names,
                           llvm::Twine(title) + opName + blockName);
        }
      }
    }
  }

  void runOnModule() override { processModule(getModule()); }

private:
  llvm::raw_ostream &os;
  std::string title;
  int unnamedOpCtr = 0;
  bool short_names;
};
} // namespace

void mlir::viewGraph(mlir::Block &block, const llvm::Twine &name,
                     bool shortNames, const llvm::Twine &title,
                     llvm::GraphProgram::Name program) {
  llvm::ViewGraph(&block, name, shortNames, title, program);
}

llvm::raw_ostream &mlir::writeGraph(llvm::raw_ostream &os, mlir::Block &block,
                                    bool shortNames, const llvm::Twine &title) {
  return llvm::WriteGraph(os, &block, shortNames, title);
}

std::unique_ptr<mlir::OpPassBase<mlir::ModuleOp>>
mlir::createPrintOpGraphPass(llvm::raw_ostream &os, bool shortNames,
                             const llvm::Twine &title) {
  return std::make_unique<PrintOpPass>(os, shortNames, title);
}

static mlir::PassRegistration<PrintOpPass> pass("print-op-graph",
                                                "Print op graph per region");
<commit_msg>Dump op location in createPrintOpGraphPass for easier debugging.<commit_after>//===- ViewOpGraph.cpp - View/write op graphviz graphs --------------------===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================

#include "mlir/Transforms/ViewOpGraph.h"
#include "mlir/IR/Block.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/STLExtras.h"
#include "llvm/Support/CommandLine.h"

static llvm::cl::opt<int> elideIfLarger(
    "print-op-graph-elide-if-larger",
    llvm::cl::desc("Upper limit to emit elements attribute rather than elide"),
    llvm::cl::init(16));

namespace llvm {

// Specialize GraphTraits to treat Block as a graph of Operations as nodes and
// uses as edges.
template <> struct GraphTraits<mlir::Block *> {
  using GraphType = mlir::Block *;
  using NodeRef = mlir::Operation *;

  using ChildIteratorType = mlir::UseIterator;
  static ChildIteratorType child_begin(NodeRef n) {
    return ChildIteratorType(n);
  }
  static ChildIteratorType child_end(NodeRef n) {
    return ChildIteratorType(n, /*end=*/true);
  }

  // Operation's destructor is private so use Operation* instead and use
  // mapped iterator.
  static mlir::Operation *AddressOf(mlir::Operation &op) { return &op; }
  using nodes_iterator =
      mapped_iterator<mlir::Block::iterator, decltype(&AddressOf)>;
  static nodes_iterator nodes_begin(mlir::Block *b) {
    return nodes_iterator(b->begin(), &AddressOf);
  }
  static nodes_iterator nodes_end(mlir::Block *b) {
    return nodes_iterator(b->end(), &AddressOf);
  }
};

// Specialize DOTGraphTraits to produce more readable output.
template <>
struct DOTGraphTraits<mlir::Block *> : public DefaultDOTGraphTraits {
  using DefaultDOTGraphTraits::DefaultDOTGraphTraits;
  static std::string getNodeLabel(mlir::Operation *op, mlir::Block *);
};

std::string DOTGraphTraits<mlir::Block *>::getNodeLabel(mlir::Operation *op,
                                                        mlir::Block *b) {
  // Reuse the print output for the node labels.
  std::string ostr;
  raw_string_ostream os(ostr);
  os << op->getName() << "\n";

  if (!op->getLoc().isa<mlir::UnknownLoc>()) {
    os << op->getLoc() << "\n";
  }

  // Print resultant types
  mlir::interleaveComma(op->getResultTypes(), os);
  os << "\n";

  for (auto attr : op->getAttrs()) {
    os << '\n' << attr.first << ": ";
    // Always emit splat attributes.
    if (attr.second.isa<mlir::SplatElementsAttr>()) {
      attr.second.print(os);
      continue;
    }

    // Elide "big" elements attributes.
    auto elements = attr.second.dyn_cast<mlir::ElementsAttr>();
    if (elements && elements.getNumElements() > elideIfLarger) {
      os << std::string(elements.getType().getRank(), '[') << "..."
         << std::string(elements.getType().getRank(), ']') << " : "
         << elements.getType();
      continue;
    }

    // Print all other attributes.
    attr.second.print(os);
  }
  return os.str();
}

} // end namespace llvm

namespace {
// PrintOpPass is simple pass to write graph per function.
// Note: this is a module pass only to avoid interleaving on the same ostream
// due to multi-threading over functions.
struct PrintOpPass : public mlir::ModulePass<PrintOpPass> {
  explicit PrintOpPass(llvm::raw_ostream &os = llvm::errs(),
                       bool short_names = false, const llvm::Twine &title = "")
      : os(os), title(title.str()), short_names(short_names) {}

  std::string getOpName(mlir::Operation &op) {
    auto symbolAttr = op.getAttrOfType<mlir::StringAttr>(
        mlir::SymbolTable::getSymbolAttrName());
    if (symbolAttr)
      return symbolAttr.getValue();
    ++unnamedOpCtr;
    return (op.getName().getStringRef() + llvm::utostr(unnamedOpCtr)).str();
  }

  // Print all the ops in a module.
  void processModule(mlir::ModuleOp module) {
    for (mlir::Operation &op : module) {
      // Modules may actually be nested, recurse on nesting.
      if (auto nestedModule = llvm::dyn_cast<mlir::ModuleOp>(op)) {
        processModule(nestedModule);
        continue;
      }
      auto opName = getOpName(op);
      for (mlir::Region &region : op.getRegions()) {
        for (auto indexed_block : llvm::enumerate(region)) {
          // Suffix block number if there are more than 1 block.
          auto blockName = region.getBlocks().size() == 1
                               ? ""
                               : ("__" + llvm::utostr(indexed_block.index()));
          llvm::WriteGraph(os, &indexed_block.value(), short_names,
                           llvm::Twine(title) + opName + blockName);
        }
      }
    }
  }

  void runOnModule() override { processModule(getModule()); }

private:
  llvm::raw_ostream &os;
  std::string title;
  int unnamedOpCtr = 0;
  bool short_names;
};
} // namespace

void mlir::viewGraph(mlir::Block &block, const llvm::Twine &name,
                     bool shortNames, const llvm::Twine &title,
                     llvm::GraphProgram::Name program) {
  llvm::ViewGraph(&block, name, shortNames, title, program);
}

llvm::raw_ostream &mlir::writeGraph(llvm::raw_ostream &os, mlir::Block &block,
                                    bool shortNames, const llvm::Twine &title) {
  return llvm::WriteGraph(os, &block, shortNames, title);
}

std::unique_ptr<mlir::OpPassBase<mlir::ModuleOp>>
mlir::createPrintOpGraphPass(llvm::raw_ostream &os, bool shortNames,
                             const llvm::Twine &title) {
  return std::make_unique<PrintOpPass>(os, shortNames, title);
}

static mlir::PassRegistration<PrintOpPass> pass("print-op-graph",
                                                "Print op graph per region");
<|endoftext|>


<commit_before>/*
 * Copyright 2016 - 2019 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "../gfx.hpp"

namespace nostalgia::core {

ox::Error initGfx(Context*) {
	return OxError(1);
}

ox::Error shutdownGfx(Context*) {
}

ox::Error initConsole(Context*) {
	return OxError(1);
}

ox::Error loadTileSheet(Context*,
                        TileSheetSpace,
                        int,
                        ox::FileAddress,
                        ox::FileAddress) {
	return OxError(1);
}

void setTile(Context*, int, int, int, uint8_t) {
}

}
<commit_msg>[nostalgia/core/qt] Add missing return nostalgia::core::shutdownGfx<commit_after>/*
 * Copyright 2016 - 2019 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "../gfx.hpp"

namespace nostalgia::core {

ox::Error initGfx(Context*) {
	return OxError(1);
}

ox::Error shutdownGfx(Context*) {
	return OxError(1);
}

ox::Error initConsole(Context*) {
	return OxError(1);
}

ox::Error loadTileSheet(Context*,
                        TileSheetSpace,
                        int,
                        ox::FileAddress,
                        ox::FileAddress) {
	return OxError(1);
}

void setTile(Context*, int, int, int, uint8_t) {
}

}
<|endoftext|>


<commit_before><commit_msg>Treap added (again)<commit_after>class treap{
    struct item{
        int x, y, l, r, k;
    };
private:
    vector<item> t;
public:
    void resize(int num) {
        t.resize(num);
    }

    void init(int v, int x) {
        t[v].x = x;
        t[v].y = rand();
        t[v].l = t[v].r = 0;
        t[v].k = !!v;
    }

    void cnt(int v) {
        t[v].k = v ? t[t[v].l].k + t[t[v].r].k + 1 : 0;
    }

    void merge(int &v, int l, int r) {
        if (!l || !r) {
            v = l ? l : r;
        } else if (t[l].y > t[r].y) {
            v = l;
            merge(t[l].r, t[l].r, r);
        } else {
            v = r;
            merge(t[r].l, l, t[r].l);
        }
        cnt(v);
    }

    void split(int v, int &l, int &r, int key) {
        if (!v) {
            l = r = 0;
            return;
        }
        if (t[t[v].l].k + 1 <= key) {
            l = v;
            split(t[v].r, t[l].r, r, key - t[t[v].l].k - 1);
        } else {
            r = v;
            split(t[v].l, l, t[r].l, key);
        }
        cnt(l);
        cnt(r);
    }

    treap(int num) {
        resize(num);
        init(0, 0);
    }

    void output(int x) {
        if (!x) return;
        output(t[x].l);
        cout << t[x].x << " ";
        output(t[x].r);
    }
};<|endoftext|>