<commit_before>//===-- PPCISelDAGToDAG.cpp - PPC --pattern matching inst selector --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by <NAME> and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a pattern matching instruction selector for PowerPC,
// converting from a legalized dag to a PPC dag.
//
//===----------------------------------------------------------------------===//

#include "PPC.h"
#include "PPCTargetMachine.h"
#include "PPCISelLowering.h"
#include "PPCHazardRecognizers.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Constants.h"
#include "llvm/GlobalValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include <iostream>
#include <set>
using namespace llvm;

namespace {
  Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");
    
  //===--------------------------------------------------------------------===//
  /// PPCDAGToDAGISel - PPC specific code to select PPC machine
  /// instructions for SelectionDAG operations.
  ///
  class PPCDAGToDAGISel : public SelectionDAGISel {
    PPCTargetLowering PPCLowering;
    unsigned GlobalBaseReg;
  public:
    PPCDAGToDAGISel(PPCTargetMachine &TM)
      : SelectionDAGISel(PPCLowering),
        PPCLowering(*TM.getTargetLowering()){}
    
    virtual bool runOnFunction(Function &Fn) {
      // Make sure we re-emit a set of the global base reg if necessary
      GlobalBaseReg = 0;
      return SelectionDAGISel::runOnFunction(Fn);
    }
   
    /// getI32Imm - Return a target constant with the specified value, of type
    /// i32.
    inline SDOperand getI32Imm(unsigned Imm) {
      return CurDAG->getTargetConstant(Imm, MVT::i32);
    }

    /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
    /// base register.  Return the virtual register that holds this value.
    SDOperand getGlobalBaseReg();
    
    // Select - Convert the specified operand from a target-independent to a
    // target-specific node if it hasn't already been changed.
    void Select(SDOperand &Result, SDOperand Op);
    
    SDNode *SelectBitfieldInsert(SDNode *N);

    /// SelectCC - Select a comparison of the specified values with the
    /// specified condition code, returning the CR# of the expression.
    SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC);

    /// SelectAddrImm - Returns true if the address N can be represented by
    /// a base register plus a signed 16-bit displacement [r+imm].
    bool SelectAddrImm(SDOperand N, SDOperand &Disp, SDOperand &Base);
      
    /// SelectAddrIdx - Given the specified addressed, check to see if it can be
    /// represented as an indexed [r+r] operation.  Returns false if it can
    /// be represented by [r+imm], which are preferred.
    bool SelectAddrIdx(SDOperand N, SDOperand &Base, SDOperand &Index);
    
    /// SelectAddrIdxOnly - Given the specified addressed, force it to be
    /// represented as an indexed [r+r] operation.
    bool SelectAddrIdxOnly(SDOperand N, SDOperand &Base, SDOperand &Index);

    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
    /// inline asm expressions.
    virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
                                              char ConstraintCode,
                                              std::vector<SDOperand> &OutOps,
                                              SelectionDAG &DAG) {
      SDOperand Op0, Op1;
      switch (ConstraintCode) {
      default: return true;
      case 'm':   // memory
        if (!SelectAddrIdx(Op, Op0, Op1))
          SelectAddrImm(Op, Op0, Op1);
        break;
      case 'o':   // offsetable
        if (!SelectAddrImm(Op, Op0, Op1)) {
          Select(Op0, Op);     // r+0.
          Op1 = getI32Imm(0);
        }
        break;
      case 'v':   // not offsetable
        SelectAddrIdxOnly(Op, Op0, Op1);
        break;
      }
      
      OutOps.push_back(Op0);
      OutOps.push_back(Op1);
      return false;
    }
    
    SDOperand BuildSDIVSequence(SDNode *N);
    SDOperand BuildUDIVSequence(SDNode *N);
    
    /// InstructionSelectBasicBlock - This callback is invoked by
    /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
    virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
    
    virtual const char *getPassName() const {
      return "PowerPC DAG->DAG Pattern Instruction Selection";
    } 
    
    /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for this
    /// target when scheduling the DAG.
    virtual HazardRecognizer *CreateTargetHazardRecognizer() {
      // Should use subtarget info to pick the right hazard recognizer.  For
      // now, always return a PPC970 recognizer.
      const TargetInstrInfo *II = PPCLowering.getTargetMachine().getInstrInfo();
      assert(II && "No InstrInfo?");
      return new PPCHazardRecognizer970(*II); 
    }

// Include the pieces autogenerated from the target description.
#include "PPCGenDAGISel.inc"
    
private:
    SDOperand SelectSETCC(SDOperand Op);
    SDOperand SelectCALL(SDOperand Op);
  };
}

/// InstructionSelectBasicBlock - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
  DEBUG(BB->dump());
  
  // The selection process is inherently a bottom-up recursive process (users
  // select their uses before themselves).  Given infinite stack space, we
  // could just start selecting on the root and traverse the whole graph.  In
  // practice however, this causes us to run out of stack space on large basic
  // blocks.  To avoid this problem, select the entry node, then all its uses,
  // iteratively instead of recursively.
  std::vector<SDOperand> Worklist;
  Worklist.push_back(DAG.getEntryNode());
  
  // Note that we can do this in the PPC target (scanning forward across token
  // chain edges) because no nodes ever get folded across these edges.  On a
  // target like X86 which supports load/modify/store operations, this would
  // have to be more careful.
  while (!Worklist.empty()) {
    SDOperand Node = Worklist.back();
    Worklist.pop_back();
    
    // Chose from the least deep of the top two nodes.
    if (!Worklist.empty() &&
        Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth())
      std::swap(Worklist.back(), Node);
    
    if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
         Node.Val->getOpcode() < PPCISD::FIRST_NUMBER) ||
        CodeGenMap.count(Node)) continue;
    
    for (SDNode::use_iterator UI = Node.Val->use_begin(),
         E = Node.Val->use_end(); UI != E; ++UI) {
      // Scan the values.  If this use has a value that is a token chain, add it
      // to the worklist.
      SDNode *User = *UI;
      for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
        if (User->getValueType(i) == MVT::Other) {
          Worklist.push_back(SDOperand(User, i));
          break; 
        }
    }

    // Finally, legalize this node.
    SDOperand Dummy;
    Select(Dummy, Node);
  }
    
  // Select target instructions for the DAG.
  DAG.setRoot(SelectRoot(DAG.getRoot()));
  CodeGenMap.clear();
  DAG.RemoveDeadNodes();
  
  // Emit machine code to BB.
  ScheduleAndEmitDAG(DAG);
  
  // Check to see if this function uses vector registers, which means we have to
  // save and restore the VRSAVE register and update it with the regs we use.  
  //
  // In this case, there will be virtual registers of vector type type created
  // by the scheduler.  Detect them now.
  SSARegMap *RegMap = DAG.getMachineFunction().getSSARegMap();
  bool HasVectorVReg = false;
  for (unsigned i = MRegisterInfo::FirstVirtualRegister, 
       e = RegMap->getLastVirtReg()+1; i != e; ++i)
    if (RegMap->getRegClass(i) == &PPC::VRRCRegClass) {
      HasVectorVReg = true;
      break;
    }
  
  // If we have a vector register, we want to emit code into the entry and exit
  // blocks to save and restore the VRSAVE register.  We do this here (instead
  // of marking all vector instructions as clobbering VRSAVE) for two reasons:
  //
  // 1. This (trivially) reduces the load on the register allocator, by not
  //    having to represent the live range of the VRSAVE register.
  // 2. This (more significantly) allows us to create a temporary virtual
  //    register to hold the saved VRSAVE value, allowing this temporary to be
  //    register allocated, instead of forcing it to be spilled to the stack.
  if (HasVectorVReg) {
    // Create two vregs - one to hold the VRSAVE register that is live-in to the
    // function and one for the value after having bits or'd into it.
    unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
    unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
    
    MachineFunction &MF = DAG.getMachineFunction();
    MachineBasicBlock &EntryBB = *MF.begin();
    // Emit the following code into the entry block:
    // InVRSAVE = MFVRSAVE
    // UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
    // MTVRSAVE UpdatedVRSAVE
    MachineBasicBlock::iterator IP = EntryBB.begin();  // Insert Point
    BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE);
    BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, UpdatedVRSAVE).addReg(InVRSAVE);
    BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE);
    
    // Find all return blocks, outputting a restore in each epilog.
    const TargetInstrInfo &TII = *DAG.getTarget().getInstrInfo();
    for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
      if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) {
        IP = BB->end(); --IP;
        
        // Skip over all terminator instructions, which are part of the return
        // sequence.
        MachineBasicBlock::iterator I2 = IP;
        while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode()))
          IP = I2;
        
        // Emit: MTVRSAVE InVRSave
        BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE);
      }        
  }
}

/// getGlobalBaseReg - Output the instructions required to put the
/// base address to use for accessing globals into a register.
///
SDOperand PPCDAGToDAGISel::getGlobalBaseReg() {
  if (!GlobalBaseReg) {
    // Insert the set of GlobalBaseReg into the first MBB of the function
    MachineBasicBlock &FirstMBB = BB->getParent()->front();
    MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    SSARegMap *RegMap = BB->getParent()->getSSARegMap();
    // FIXME: when we get to LP64, we will need to create the appropriate
    // type of register here.
    GlobalBaseReg = RegMap->createVirtualRegister(PPC::GPRCRegisterClass);
    BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
    BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
  }
  return CurDAG->getRegister(GlobalBaseReg, MVT::i32);
}


// isIntImmediate - This method tests to see if a constant operand.
// If so Imm will receive the 32 bit value.
static bool isIntImmediate(SDNode *N, unsigned& Imm) {
  if (N->getOpcode() == ISD::Constant) {<commit_msg>Save/restore VRSAVE once per function, not once per block.<commit_after>//===-- PPCISelDAGToDAG.cpp - PPC --pattern matching inst selector --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by <NAME> and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a pattern matching instruction selector for PowerPC,
// converting from a legalized dag to a PPC dag.
//
//===----------------------------------------------------------------------===//

#include "PPC.h"
#include "PPCTargetMachine.h"
#include "PPCISelLowering.h"
#include "PPCHazardRecognizers.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Constants.h"
#include "llvm/GlobalValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include <iostream>
#include <set>
using namespace llvm;

namespace {
  Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");
    
  //===--------------------------------------------------------------------===//
  /// PPCDAGToDAGISel - PPC specific code to select PPC machine
  /// instructions for SelectionDAG operations.
  ///
  class PPCDAGToDAGISel : public SelectionDAGISel {
    PPCTargetMachine &TM;
    PPCTargetLowering PPCLowering;
    unsigned GlobalBaseReg;
  public:
    PPCDAGToDAGISel(PPCTargetMachine &tm)
      : SelectionDAGISel(PPCLowering), TM(tm),
        PPCLowering(*TM.getTargetLowering()) {}
    
    virtual bool runOnFunction(Function &Fn) {
      // Make sure we re-emit a set of the global base reg if necessary
      GlobalBaseReg = 0;
      SelectionDAGISel::runOnFunction(Fn);
      
      InsertVRSaveCode(Fn);
      return true;
    }
   
    /// getI32Imm - Return a target constant with the specified value, of type
    /// i32.
    inline SDOperand getI32Imm(unsigned Imm) {
      return CurDAG->getTargetConstant(Imm, MVT::i32);
    }

    /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
    /// base register.  Return the virtual register that holds this value.
    SDOperand getGlobalBaseReg();
    
    // Select - Convert the specified operand from a target-independent to a
    // target-specific node if it hasn't already been changed.
    void Select(SDOperand &Result, SDOperand Op);
    
    SDNode *SelectBitfieldInsert(SDNode *N);

    /// SelectCC - Select a comparison of the specified values with the
    /// specified condition code, returning the CR# of the expression.
    SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC);

    /// SelectAddrImm - Returns true if the address N can be represented by
    /// a base register plus a signed 16-bit displacement [r+imm].
    bool SelectAddrImm(SDOperand N, SDOperand &Disp, SDOperand &Base);
      
    /// SelectAddrIdx - Given the specified addressed, check to see if it can be
    /// represented as an indexed [r+r] operation.  Returns false if it can
    /// be represented by [r+imm], which are preferred.
    bool SelectAddrIdx(SDOperand N, SDOperand &Base, SDOperand &Index);
    
    /// SelectAddrIdxOnly - Given the specified addressed, force it to be
    /// represented as an indexed [r+r] operation.
    bool SelectAddrIdxOnly(SDOperand N, SDOperand &Base, SDOperand &Index);

    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
    /// inline asm expressions.
    virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
                                              char ConstraintCode,
                                              std::vector<SDOperand> &OutOps,
                                              SelectionDAG &DAG) {
      SDOperand Op0, Op1;
      switch (ConstraintCode) {
      default: return true;
      case 'm':   // memory
        if (!SelectAddrIdx(Op, Op0, Op1))
          SelectAddrImm(Op, Op0, Op1);
        break;
      case 'o':   // offsetable
        if (!SelectAddrImm(Op, Op0, Op1)) {
          Select(Op0, Op);     // r+0.
          Op1 = getI32Imm(0);
        }
        break;
      case 'v':   // not offsetable
        SelectAddrIdxOnly(Op, Op0, Op1);
        break;
      }
      
      OutOps.push_back(Op0);
      OutOps.push_back(Op1);
      return false;
    }
    
    SDOperand BuildSDIVSequence(SDNode *N);
    SDOperand BuildUDIVSequence(SDNode *N);
    
    /// InstructionSelectBasicBlock - This callback is invoked by
    /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
    virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
    
    void InsertVRSaveCode(Function &Fn);

    virtual const char *getPassName() const {
      return "PowerPC DAG->DAG Pattern Instruction Selection";
    } 
    
    /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for this
    /// target when scheduling the DAG.
    virtual HazardRecognizer *CreateTargetHazardRecognizer() {
      // Should use subtarget info to pick the right hazard recognizer.  For
      // now, always return a PPC970 recognizer.
      const TargetInstrInfo *II = PPCLowering.getTargetMachine().getInstrInfo();
      assert(II && "No InstrInfo?");
      return new PPCHazardRecognizer970(*II); 
    }

// Include the pieces autogenerated from the target description.
#include "PPCGenDAGISel.inc"
    
private:
    SDOperand SelectSETCC(SDOperand Op);
    SDOperand SelectCALL(SDOperand Op);
  };
}

/// InstructionSelectBasicBlock - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
  DEBUG(BB->dump());
  
  // The selection process is inherently a bottom-up recursive process (users
  // select their uses before themselves).  Given infinite stack space, we
  // could just start selecting on the root and traverse the whole graph.  In
  // practice however, this causes us to run out of stack space on large basic
  // blocks.  To avoid this problem, select the entry node, then all its uses,
  // iteratively instead of recursively.
  std::vector<SDOperand> Worklist;
  Worklist.push_back(DAG.getEntryNode());
  
  // Note that we can do this in the PPC target (scanning forward across token
  // chain edges) because no nodes ever get folded across these edges.  On a
  // target like X86 which supports load/modify/store operations, this would
  // have to be more careful.
  while (!Worklist.empty()) {
    SDOperand Node = Worklist.back();
    Worklist.pop_back();
    
    // Chose from the least deep of the top two nodes.
    if (!Worklist.empty() &&
        Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth())
      std::swap(Worklist.back(), Node);
    
    if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
         Node.Val->getOpcode() < PPCISD::FIRST_NUMBER) ||
        CodeGenMap.count(Node)) continue;
    
    for (SDNode::use_iterator UI = Node.Val->use_begin(),
         E = Node.Val->use_end(); UI != E; ++UI) {
      // Scan the values.  If this use has a value that is a token chain, add it
      // to the worklist.
      SDNode *User = *UI;
      for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
        if (User->getValueType(i) == MVT::Other) {
          Worklist.push_back(SDOperand(User, i));
          break; 
        }
    }

    // Finally, legalize this node.
    SDOperand Dummy;
    Select(Dummy, Node);
  }
    
  // Select target instructions for the DAG.
  DAG.setRoot(SelectRoot(DAG.getRoot()));
  CodeGenMap.clear();
  DAG.RemoveDeadNodes();
  
  // Emit machine code to BB.
  ScheduleAndEmitDAG(DAG);
}

/// InsertVRSaveCode - Once the entire function has been instruction selected,
/// all virtual registers are created and all machine instructions are built,
/// check to see if we need to save/restore VRSAVE.  If so, do it.
void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) {
  // Check to see if this function uses vector registers, which means we have to
  // save and restore the VRSAVE register and update it with the regs we use.  
  //
  // In this case, there will be virtual registers of vector type type created
  // by the scheduler.  Detect them now.
  MachineFunction &Fn = MachineFunction::get(&F);
  SSARegMap *RegMap = Fn.getSSARegMap();
  bool HasVectorVReg = false;
  for (unsigned i = MRegisterInfo::FirstVirtualRegister, 
       e = RegMap->getLastVirtReg()+1; i != e; ++i)
    if (RegMap->getRegClass(i) == &PPC::VRRCRegClass) {
      HasVectorVReg = true;
      break;
    }
  if (!HasVectorVReg) return;  // nothing to do.
      
  // If we have a vector register, we want to emit code into the entry and exit
  // blocks to save and restore the VRSAVE register.  We do this here (instead
  // of marking all vector instructions as clobbering VRSAVE) for two reasons:
  //
  // 1. This (trivially) reduces the load on the register allocator, by not
  //    having to represent the live range of the VRSAVE register.
  // 2. This (more significantly) allows us to create a temporary virtual
  //    register to hold the saved VRSAVE value, allowing this temporary to be
  //    register allocated, instead of forcing it to be spilled to the stack.

  // Create two vregs - one to hold the VRSAVE register that is live-in to the
  // function and one for the value after having bits or'd into it.
  unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
  unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
  
  MachineBasicBlock &EntryBB = *Fn.begin();
  // Emit the following code into the entry block:
  // InVRSAVE = MFVRSAVE
  // UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
  // MTVRSAVE UpdatedVRSAVE
  MachineBasicBlock::iterator IP = EntryBB.begin();  // Insert Point
  BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE);
  BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, UpdatedVRSAVE).addReg(InVRSAVE);
  BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE);
  
  // Find all return blocks, outputting a restore in each epilog.
  const TargetInstrInfo &TII = *TM.getInstrInfo();
  for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
    if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) {
      IP = BB->end(); --IP;
      
      // Skip over all terminator instructions, which are part of the return
      // sequence.
      MachineBasicBlock::iterator I2 = IP;
      while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode()))
        IP = I2;
      
      // Emit: MTVRSAVE InVRSave
      BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE);
    }        
  }
}


/// getGlobalBaseReg - Output the instructions required to put the
/// base address to use for accessing globals into a register.
///
SDOperand PPCDAGToDAGISel::getGlobalBaseReg() {
  if (!GlobalBaseReg) {
    // Insert the set of GlobalBaseReg into the first MBB of the function
    MachineBasicBlock &FirstMBB = BB->getParent()->front();
    MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    SSARegMap *RegMap = BB->getParent()->getSSARegMap();
    // FIXME: when we get to LP64, we will need to create the appropriate
    // type of register here.
    GlobalBaseReg = RegMap->createVirtualRegister(PPC::GPRCRegisterClass);
    BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
    BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
  }
  return CurDAG->getRegister(GlobalBaseReg, MVT::i32);
}


// isIntImmediate - This method tests to see if a constant operand.
// If so Imm will receive the 32 bit value.
static bool isIntImmediate(SDNode *N, unsigned& Imm) {
  if (N->getOpcode() == ISD::Constant) {
{'fraction_non_alphanumeric': 0.12357543799965981, 'fraction_numerical': 0.004847763225038272, 'mean_word_length': 2.706967213114754, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7542874', 'n_tokens_mistral': 7092, 'n_tokens_neox': 6983, 'n_words': 2280}