<commit_before>/*
 * Instrument code to keep track of run-time behavior:
 * LLVM pass initialization
 *
 * By <NAME> <<EMAIL>>
 *    <NAME> <<EMAIL>>
 *    <NAME> <<EMAIL>>
 */

#include "bytesflops.h"

namespace bytesflops_pass {

  // Prepend a function to the list of constructors.
  static void prepend_to_ctor_list (Module* module, Function* func) {
    // Determine the number of elements in the final array.
    LLVMContext& globctx = module->getContext();
    GlobalVariable* existing_ctors =
      module->getGlobalVariable("llvm.global_ctors");
    unsigned int numelts = 1;
    if (existing_ctors != nullptr)
      if (PointerType* ctor_type = dyn_cast<PointerType>(existing_ctors->getType()))
        if (ArrayType* array = dyn_cast<ArrayType>(ctor_type->getPointerElementType()))
          numelts += array->getNumElements();

    // Define a new constructors array.
    std::vector<Type*> no_args;
    FunctionType* thunk =
      FunctionType::get(Type::getVoidTy(globctx), no_args, false);
    PointerType* ptr_to_thunk = PointerType::get(thunk, 0);
    std::vector<Type*>ctor_record_fields;
    ctor_record_fields.push_back(IntegerType::get(globctx, 32));
    ctor_record_fields.push_back(ptr_to_thunk);
    PointerType* null_pointer =
      PointerType::get(IntegerType::get(globctx, 8), 0);
    ctor_record_fields.push_back(null_pointer);
    StructType *ctor_record =
      StructType::get(globctx, ctor_record_fields, false);
    ArrayType* ctor_array = ArrayType::get(ctor_record, numelts);

    // Wrap the given function in a ctor_record and insert that into the
    // constructor array.
    std::vector<Constant*> ctor_elems;
    std::vector<Constant*> ctor_elem_fields;
    ctor_elem_fields.push_back(ConstantInt::get(globctx, APInt(32, StringRef("65535"), 10)));
    ctor_elem_fields.push_back(func);
    ctor_elems.push_back(ConstantStruct::get(ctor_record, ctor_elem_fields));

    // Prepend the existing constructors to the new array.
    if (existing_ctors != nullptr) {
      Constant* initializer = existing_ctors->getInitializer();
      if (isa<ConstantArray>(initializer) || isa<ConstantAggregateZero>(initializer)) {
        for (unsigned int e = 0; e < numelts - 1; e++) {
          Constant* elt = initializer->getAggregateElement(e);
          assert(isa<ConstantStruct>(elt));
          ctor_elems.push_back(elt);
        }
      }
      else
        report_fatal_error("Encountered unexpected type of llvm.global_ctors");
    }

    // Remove the old constructor array (if any) and create a new constructor
    // array.
    if (existing_ctors != nullptr)
      existing_ctors->eraseFromParent();
    Constant* new_ctors = ConstantArray::get(ctor_array, ctor_elems);
    GlobalVariable* llvm_global_ctors =
      new GlobalVariable(*module, ctor_array, false, GlobalValue::AppendingLinkage,
                         new_ctors, "llvm.global_ctors");
  }

  /* Create a module constructor function to create the map from function keys
   * to function names.  This function will be automatically called when the
   * module is loaded. */
  void BytesFlops::initializeKeyMap(Module* module) {<commit_msg>Corrected generation of the constructor list<commit_after>/*
 * Instrument code to keep track of run-time behavior:
 * LLVM pass initialization
 *
 * By <NAME> <<EMAIL>>
 *    <NAME> <<EMAIL>>
 *    <NAME> <<EMAIL>>
 */

#include "bytesflops.h"

namespace bytesflops_pass {

  // Prepend a function to the list of constructors.
  static void prepend_to_ctor_list (Module* module, Function* func) {
    // Determine the number of elements in the final array.
    LLVMContext& globctx = module->getContext();
    GlobalVariable* existing_ctors =
      module->getGlobalVariable("llvm.global_ctors");
    unsigned int numelts = 1;
    if (existing_ctors != nullptr)
      if (PointerType* ctor_type = dyn_cast<PointerType>(existing_ctors->getType()))
        if (ArrayType* array = dyn_cast<ArrayType>(ctor_type->getPointerElementType()))
          numelts += array->getNumElements();

    // Define a new constructors array.
    std::vector<Type*> no_args;
    FunctionType* thunk =
      FunctionType::get(Type::getVoidTy(globctx), no_args, false);
    PointerType* ptr_to_thunk = PointerType::get(thunk, 0);
    std::vector<Type*>ctor_record_fields;
    ctor_record_fields.push_back(IntegerType::get(globctx, 32));
    ctor_record_fields.push_back(ptr_to_thunk);
    Constant* null_pointer =
      ConstantPointerNull::get(PointerType::get(IntegerType::get(globctx, 8), 0));
    ctor_record_fields.push_back(null_pointer->getType());
    StructType *ctor_record =
      StructType::get(globctx, ctor_record_fields, false);
    ArrayType* ctor_array = ArrayType::get(ctor_record, numelts);

    // Wrap the given function in a ctor_record and insert that into the
    // constructor array.
    std::vector<Constant*> ctor_elems;
    std::vector<Constant*> ctor_elem_fields;
    ctor_elem_fields.push_back(ConstantInt::get(globctx, APInt(32, StringRef("65535"), 10)));
    ctor_elem_fields.push_back(func);
    ctor_elem_fields.push_back(null_pointer);
    ctor_elems.push_back(ConstantStruct::get(ctor_record, ctor_elem_fields));

    // Prepend the existing constructors to the new array.
    if (existing_ctors != nullptr) {
      Constant* initializer = existing_ctors->getInitializer();
      if (isa<ConstantArray>(initializer) || isa<ConstantAggregateZero>(initializer)) {
        for (unsigned int e = 0; e < numelts - 1; e++) {
          Constant* elt = initializer->getAggregateElement(e);
          assert(isa<ConstantStruct>(elt));
          ctor_elems.push_back(elt);
        }
      }
      else
        report_fatal_error("Encountered unexpected type of llvm.global_ctors");
    }

    // Remove the old constructor array (if any) and create a new constructor
    // array.
    if (existing_ctors != nullptr)
      existing_ctors->eraseFromParent();
    Constant* new_ctors = ConstantArray::get(ctor_array, ctor_elems);
    GlobalVariable* llvm_global_ctors =
      new GlobalVariable(*module, ctor_array, false, GlobalValue::AppendingLinkage,
                         new_ctors, "llvm.global_ctors");
  }

  /* Create a module constructor function to create the map from function keys
   * to function names.  This function will be automatically called when the
   * module is loaded. */
  void BytesFlops::initializeKeyMap(Module* module) {
{'fraction_non_alphanumeric': 0.11251758087201125, 'fraction_numerical': 0.005313330207844975, 'mean_word_length': 3.8743335872048745, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6475875', 'n_tokens_mistral': 1956, 'n_tokens_neox': 1908, 'n_words': 458}