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

#include "HexagonBitTracker.h"
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <utility>
#include <vector>

using namespace llvm;

using BT = BitTracker;

HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri,
                                   MachineRegisterInfo &mri,
                                   const HexagonInstrInfo &tii,
                                   MachineFunction &mf)
    : MachineEvaluator(tri, mri), MF(mf), MFI(mf.getFrameInfo()), TII(tii) {
  // Populate the VRX map (VR to extension-type).
  // Go over all the formal parameters of the function. If a given parameter
  // P is sign- or zero-extended, locate the virtual register holding that
  // parameter and create an entry in the VRX map indicating the type of ex-
  // tension (and the source type).
  // This is a bit complicated to do accurately, since the memory layout in-
  // formation is necessary to precisely determine whether an aggregate para-
  // meter will be passed in a register or in memory. What is given in MRI
  // is the association between the physical register that is live-in (i.e.
  // holds an argument), and the virtual register that this value will be
  // copied into. This, by itself, is not sufficient to map back the virtual
  // register to a formal parameter from Function (since consecutive live-ins
  // from MRI may not correspond to consecutive formal parameters from Func-
  // tion). To avoid the complications with in-memory arguments, only consi-
  // der the initial sequence of formal parameters that are known to be
  // passed via registers.
  unsigned InVirtReg, InPhysReg = 0;
  const Function &F = *MF.getFunction();

  using arg_iterator = Function::const_arg_iterator;

  for (arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
    const Argument &Arg = *I;
    Type *ATy = Arg.getType();
    unsigned Width = 0;
    if (ATy->isIntegerTy())
      Width = ATy->getIntegerBitWidth();
    else if (ATy->isPointerTy())
      Width = 32;
    // If pointer size is not set through target data, it will default to
    // Module::AnyPointerSize.
    if (Width == 0 || Width > 64)
      break;
    if (Arg.hasAttribute(Attribute::ByVal))
      continue;
    InPhysReg = getNextPhysReg(InPhysReg, Width);
    if (!InPhysReg)
      break;
    InVirtReg = getVirtRegFor(InPhysReg);
    if (!InVirtReg)
      continue;
    if (Arg.hasAttribute(Attribute::SExt))
      VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::SExt, Width)));
    else if (Arg.hasAttribute(Attribute::ZExt))
      VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::ZExt, Width)));
  }
}

BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
  if (Sub == 0)
    return MachineEvaluator::mask(Reg, 0);
  const TargetRegisterClass &RC = *MRI.getRegClass(Reg);
  unsigned ID = RC.getID();
  uint16_t RW = getRegBitWidth(RegisterRef(Reg, Sub));
  auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
  bool IsSubLo = (Sub == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
  switch (ID) {
    case Hexagon::DoubleRegsRegClassID:
    case Hexagon::HvxWRRegClassID:
      return IsSubLo ? BT::BitMask(0, RW-1)
                     : BT::BitMask(RW, 2*RW-1);
    default:
      break;
  }
#ifndef NDEBUG
  dbgs() << PrintReg(Reg, &TRI, Sub) << " in reg class "
         << TRI.getRegClassName(&RC) << '\n';
#endif
  llvm_unreachable("Unexpected register/subregister");
}

uint16_t HexagonEvaluator::getPhysRegBitWidth(unsigned Reg) const {
  assert(TargetRegisterInfo::isPhysicalRegister(Reg));

  using namespace Hexagon;
  for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass})
    if (RC.contains(Reg))
      return TRI.getRegSizeInBits(RC);
  // Default treatment for other physical registers.
  if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg))
    return TRI.getRegSizeInBits(*RC);

  llvm_unreachable(
      (Twine("Unhandled physical register") + TRI.getName(Reg)).str().c_str());
}

const TargetRegisterClass &HexagonEvaluator::composeWithSubRegIndex(
      const TargetRegisterClass &RC, unsigned Idx) const {
  if (Idx == 0)
    return RC;

#ifndef NDEBUG
  const auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
  bool IsSubLo = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
  bool IsSubHi = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_hi));
  assert(IsSubLo != IsSubHi && "Must refer to either low or high subreg");
#endif

  switch (RC.getID()) {
    case Hexagon::DoubleRegsRegClassID:
      return Hexagon::IntRegsRegClass;
    case Hexagon::HvxWRRegClassID:
      return Hexagon::HvxVRRegClass;
    default:
      break;
  }
#ifndef DEBUG
  dbgs() << "Reg class id: " << RC.getID() << " idx: " << Idx << '\n';
#endif
  llvm_unreachable("Unimplemented combination of reg class/subreg idx");
}

namespace {

class RegisterRefs {
  std::vector<BT::RegisterRef> Vector;

public:
  RegisterRefs(const MachineInstr &MI) : Vector(MI.getNumOperands()) {
    for (unsigned i = 0, n = Vector.size(); i < n; ++i) {
      const MachineOperand &MO = MI.getOperand(i);
      if (MO.isReg())
        Vector[i] = BT::RegisterRef(MO);
      // For indices that don't correspond to registers, the entry will
      // remain constructed via the default constructor.
    }
  }

  size_t size() const { return Vector.size(); }

  const BT::RegisterRef &operator[](unsigned n) const {<commit_msg>[Hexagon] Fix a typo: #ifndef DEBUG -> #ifndef NDEBUG<commit_after>//===- HexagonBitTracker.cpp ----------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "HexagonBitTracker.h"
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <utility>
#include <vector>

using namespace llvm;

using BT = BitTracker;

HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri,
                                   MachineRegisterInfo &mri,
                                   const HexagonInstrInfo &tii,
                                   MachineFunction &mf)
    : MachineEvaluator(tri, mri), MF(mf), MFI(mf.getFrameInfo()), TII(tii) {
  // Populate the VRX map (VR to extension-type).
  // Go over all the formal parameters of the function. If a given parameter
  // P is sign- or zero-extended, locate the virtual register holding that
  // parameter and create an entry in the VRX map indicating the type of ex-
  // tension (and the source type).
  // This is a bit complicated to do accurately, since the memory layout in-
  // formation is necessary to precisely determine whether an aggregate para-
  // meter will be passed in a register or in memory. What is given in MRI
  // is the association between the physical register that is live-in (i.e.
  // holds an argument), and the virtual register that this value will be
  // copied into. This, by itself, is not sufficient to map back the virtual
  // register to a formal parameter from Function (since consecutive live-ins
  // from MRI may not correspond to consecutive formal parameters from Func-
  // tion). To avoid the complications with in-memory arguments, only consi-
  // der the initial sequence of formal parameters that are known to be
  // passed via registers.
  unsigned InVirtReg, InPhysReg = 0;
  const Function &F = *MF.getFunction();

  using arg_iterator = Function::const_arg_iterator;

  for (arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
    const Argument &Arg = *I;
    Type *ATy = Arg.getType();
    unsigned Width = 0;
    if (ATy->isIntegerTy())
      Width = ATy->getIntegerBitWidth();
    else if (ATy->isPointerTy())
      Width = 32;
    // If pointer size is not set through target data, it will default to
    // Module::AnyPointerSize.
    if (Width == 0 || Width > 64)
      break;
    if (Arg.hasAttribute(Attribute::ByVal))
      continue;
    InPhysReg = getNextPhysReg(InPhysReg, Width);
    if (!InPhysReg)
      break;
    InVirtReg = getVirtRegFor(InPhysReg);
    if (!InVirtReg)
      continue;
    if (Arg.hasAttribute(Attribute::SExt))
      VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::SExt, Width)));
    else if (Arg.hasAttribute(Attribute::ZExt))
      VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::ZExt, Width)));
  }
}

BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
  if (Sub == 0)
    return MachineEvaluator::mask(Reg, 0);
  const TargetRegisterClass &RC = *MRI.getRegClass(Reg);
  unsigned ID = RC.getID();
  uint16_t RW = getRegBitWidth(RegisterRef(Reg, Sub));
  auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
  bool IsSubLo = (Sub == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
  switch (ID) {
    case Hexagon::DoubleRegsRegClassID:
    case Hexagon::HvxWRRegClassID:
      return IsSubLo ? BT::BitMask(0, RW-1)
                     : BT::BitMask(RW, 2*RW-1);
    default:
      break;
  }
#ifndef NDEBUG
  dbgs() << PrintReg(Reg, &TRI, Sub) << " in reg class "
         << TRI.getRegClassName(&RC) << '\n';
#endif
  llvm_unreachable("Unexpected register/subregister");
}

uint16_t HexagonEvaluator::getPhysRegBitWidth(unsigned Reg) const {
  assert(TargetRegisterInfo::isPhysicalRegister(Reg));

  using namespace Hexagon;
  for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass})
    if (RC.contains(Reg))
      return TRI.getRegSizeInBits(RC);
  // Default treatment for other physical registers.
  if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg))
    return TRI.getRegSizeInBits(*RC);

  llvm_unreachable(
      (Twine("Unhandled physical register") + TRI.getName(Reg)).str().c_str());
}

const TargetRegisterClass &HexagonEvaluator::composeWithSubRegIndex(
      const TargetRegisterClass &RC, unsigned Idx) const {
  if (Idx == 0)
    return RC;

#ifndef NDEBUG
  const auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
  bool IsSubLo = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
  bool IsSubHi = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_hi));
  assert(IsSubLo != IsSubHi && "Must refer to either low or high subreg");
#endif

  switch (RC.getID()) {
    case Hexagon::DoubleRegsRegClassID:
      return Hexagon::IntRegsRegClass;
    case Hexagon::HvxWRRegClassID:
      return Hexagon::HvxVRRegClass;
    default:
      break;
  }
#ifndef NDEBUG
  dbgs() << "Reg class id: " << RC.getID() << " idx: " << Idx << '\n';
#endif
  llvm_unreachable("Unimplemented combination of reg class/subreg idx");
}

namespace {

class RegisterRefs {
  std::vector<BT::RegisterRef> Vector;

public:
  RegisterRefs(const MachineInstr &MI) : Vector(MI.getNumOperands()) {
    for (unsigned i = 0, n = Vector.size(); i < n; ++i) {
      const MachineOperand &MO = MI.getOperand(i);
      if (MO.isReg())
        Vector[i] = BT::RegisterRef(MO);
      // For indices that don't correspond to registers, the entry will
      // remain constructed via the default constructor.
    }
  }

  size_t size() const { return Vector.size(); }

  const BT::RegisterRef &operator[](unsigned n) const {
{'fraction_non_alphanumeric': 0.13988118200756114, 'fraction_numerical': 0.00293187254069902, 'mean_word_length': 3.3409243134628266, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1774833', 'n_tokens_mistral': 4174, 'n_tokens_neox': 4032, 'n_words': 1145}