brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 114f5fc Raw
160 lines · cpp
1//==-- loop_proto_to_cxx.cpp - Protobuf-C++ conversion ---------------------==//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Implements functions for converting between protobufs and C++. Differs from10// proto_to_cxx.cpp by wrapping all the generated C++ code in either a single11// for loop or two nested loops. Also outputs a different function signature12// that includes a size_t parameter for the loop to use. The C++ code generated13// is meant to stress the LLVM loop vectorizer.14//15// Still a work in progress.16//17//===----------------------------------------------------------------------===//18 19#include "cxx_loop_proto.pb.h"20#include "proto_to_cxx.h"21 22// The following is needed to convert protos in human-readable form23#include <google/protobuf/text_format.h>24 25#include <ostream>26#include <sstream>27 28namespace clang_fuzzer {29 30static bool inner_loop = false;31class InnerLoop {32  public:33  InnerLoop() {34    inner_loop = true;35  }36  ~InnerLoop() {37    inner_loop = false;38  }39};40 41// Forward decls.42std::ostream &operator<<(std::ostream &os, const BinaryOp &x);43std::ostream &operator<<(std::ostream &os, const StatementSeq &x);44 45// Proto to C++.46std::ostream &operator<<(std::ostream &os, const Const &x) {47  return os << "(" << x.val() << ")";48}49std::ostream &operator<<(std::ostream &os, const VarRef &x) {50  std::string which_loop = inner_loop ? "j" : "i";51  switch (x.arr()) {52    case VarRef::ARR_A:53      return os << "a[" << which_loop << "]";54    case VarRef::ARR_B:55      return os << "b[" << which_loop << "]";56    case VarRef::ARR_C:57      return os << "c[" << which_loop << "]";58  }59}60std::ostream &operator<<(std::ostream &os, const Rvalue &x) {61  if (x.has_cons())62    return os << x.cons();63  if (x.has_binop())64    return os << x.binop();65  if (x.has_varref())66    return os << x.varref();67  return os << "1";68}69std::ostream &operator<<(std::ostream &os, const BinaryOp &x) {70  os << "(" << x.left();71  switch (x.op()) {72  case BinaryOp::PLUS:73    os << "+";74    break;75  case BinaryOp::MINUS:76    os << "-";77    break;78  case BinaryOp::MUL:79    os << "*";80    break;81  case BinaryOp::XOR:82    os << "^";83    break;84  case BinaryOp::AND:85    os << "&";86    break;87  case BinaryOp::OR:88    os << "|";89    break;90  case BinaryOp::EQ:91    os << "==";92    break;93  case BinaryOp::NE:94    os << "!=";95    break;96  case BinaryOp::LE:97    os << "<=";98    break;99  case BinaryOp::GE:100    os << ">=";101    break;102  case BinaryOp::LT:103    os << "<";104    break;105  case BinaryOp::GT:106    os << ">";107    break;108  }109  return os << x.right() << ")";110}111std::ostream &operator<<(std::ostream &os, const AssignmentStatement &x) {112  return os << x.varref() << "=" << x.rvalue() << ";\n";113}114std::ostream &operator<<(std::ostream &os, const Statement &x) {115  return os << x.assignment();116}117std::ostream &operator<<(std::ostream &os, const StatementSeq &x) {118  for (auto &st : x.statements())119    os << st;120  return os;121}122void NestedLoopToString(std::ostream &os, const LoopFunction &x) {123  os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n"124     << "for (int i=0; i<s; i++){\n"125     << "for (int j=0; j<s; j++){\n";126  {127    InnerLoop IL;128    os << x.inner_statements() << "}\n";129  }130  os << x.outer_statements() << "}\n}\n";131}132void SingleLoopToString(std::ostream &os, const LoopFunction &x) {133  os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n"134     << "for (int i=0; i<s; i++){\n"135     << x.outer_statements() << "}\n}\n";136}137std::ostream &operator<<(std::ostream &os, const LoopFunction &x) {138  if (x.has_inner_statements())139    NestedLoopToString(os, x);140  else141    SingleLoopToString(os, x);142  return os;143}144 145// ---------------------------------146 147std::string LoopFunctionToString(const LoopFunction &input) {148  std::ostringstream os;149  os << input;150  return os.str();151}152std::string LoopProtoToCxx(const uint8_t *data, size_t size) {153  LoopFunction message;154  if (!message.ParsePartialFromArray(data, size))155    return "#error invalid proto\n";156  return LoopFunctionToString(message);157}158 159} // namespace clang_fuzzer160