<commit_before>//===- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha --===//
//
//                     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 file defines a pattern matching instruction selector for Alpha.
//
//===----------------------------------------------------------------------===//

#include "Alpha.h"
#include "AlphaRegisterInfo.h"
#include "llvm/Constants.h"                   // FIXME: REMOVE
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include <set>
#include <algorithm>
using namespace llvm;

namespace llvm {
  cl::opt<bool> EnableAlphaIDIV("enable-alpha-intfpdiv",
                             cl::desc("Use the FP div instruction for integer div when possible"),
                             cl::Hidden);
  cl::opt<bool> EnableAlphaFTOI("enable-alpha-FTOI",
                             cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"),
                             cl::Hidden);
  cl::opt<bool> EnableAlphaCT("enable-alpha-CT",
                              cl::desc("Enable use of the ctpop, ctlz, and cttz instructions"),
                              cl::Hidden);
  cl::opt<bool> EnableAlphaCount("enable-alpha-count",
                             cl::desc("Print estimates on live ins and outs"),
                             cl::Hidden);
}

//===----------------------------------------------------------------------===//
//  AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
namespace {
  class AlphaTargetLowering : public TargetLowering {
    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
    unsigned GP; //GOT vreg
  public:
    AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
      // Set up the TargetLowering object.
      //I am having problems with shr n ubyte 1
      setShiftAmountType(MVT::i64);
      setSetCCResultType(MVT::i64);
      setSetCCResultContents(ZeroOrOneSetCCResult);

      addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
      addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
      addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);

      setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
      setOperationAction(ISD::EXTLOAD  , MVT::i1   , Promote);
      setOperationAction(ISD::EXTLOAD  , MVT::f32  , Promote);

      setOperationAction(ISD::ZEXTLOAD , MVT::i1   , Expand);
      setOperationAction(ISD::ZEXTLOAD , MVT::i32  , Expand);

      setOperationAction(ISD::SEXTLOAD , MVT::i1   , Expand);
      setOperationAction(ISD::SEXTLOAD , MVT::i8   , Expand);
      setOperationAction(ISD::SEXTLOAD , MVT::i16  , Expand);

      setOperationAction(ISD::SREM     , MVT::f32  , Expand);
      setOperationAction(ISD::SREM     , MVT::f64  , Expand);

      if (!EnableAlphaCT) {
        setOperationAction(ISD::CTPOP    , MVT::i64  , Expand);
        setOperationAction(ISD::CTTZ     , MVT::i64  , Expand);
        setOperationAction(ISD::CTLZ     , MVT::i64  , Expand);
      }

      //If this didn't legalize into a div....
      //      setOperationAction(ISD::SREM     , MVT::i64, Expand);
      //      setOperationAction(ISD::UREM     , MVT::i64, Expand);

      setOperationAction(ISD::MEMMOVE  , MVT::Other, Expand);
      setOperationAction(ISD::MEMSET   , MVT::Other, Expand);
      setOperationAction(ISD::MEMCPY   , MVT::Other, Expand);

      // We don't support sin/cos/sqrt
      setOperationAction(ISD::FSIN , MVT::f64, Expand);
      setOperationAction(ISD::FCOS , MVT::f64, Expand);
      setOperationAction(ISD::FSQRT, MVT::f64, Expand);
      setOperationAction(ISD::FSIN , MVT::f32, Expand);
      setOperationAction(ISD::FCOS , MVT::f32, Expand);
      setOperationAction(ISD::FSQRT, MVT::f32, Expand);

      //Doesn't work yet
      setOperationAction(ISD::SETCC, MVT::f32,   Promote);

      computeRegisterProperties();

      addLegalFPImmediate(+0.0); //F31
      addLegalFPImmediate(-0.0); //-F31
    }

    /// LowerArguments - This hook must be implemented to indicate how we should
    /// lower the arguments for the specified function, into the specified DAG.
    virtual std::vector<SDOperand>
    LowerArguments(Function &F, SelectionDAG &DAG);

    /// LowerCallTo - This hook lowers an abstract call to a function into an
    /// actual call.
    virtual std::pair<SDOperand, SDOperand>
    LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC,
                bool isTailCall, SDOperand Callee, ArgListTy &Args,
                SelectionDAG &DAG);

    virtual std::pair<SDOperand, SDOperand>
    LowerVAStart(SDOperand Chain, SelectionDAG &DAG);

    virtual std::pair<SDOperand,SDOperand>
    LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
                   const Type *ArgTy, SelectionDAG &DAG);

    virtual std::pair<SDOperand, SDOperand>
    LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                            SelectionDAG &DAG);

    void restoreGP(MachineBasicBlock* BB)
    {
      BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
    }
  };
}

/// AddLiveIn - This helper function adds the specified physical register to the
/// MachineFunction as a live in value.  It also creates a corresponding virtual
/// register for it.
static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
                          TargetRegisterClass *RC) {
  assert(RC->contains(PReg) && "Not the correct regclass!");
  unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
  MF.addLiveIn(PReg, VReg);
  return VReg;
}

//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21

//For now, just use variable size stack frame format

//In a standard call, the first six items are passed in registers $16
//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
//of argument-to-register correspondence.) The remaining items are
//collected in a memory argument list that is a naturally aligned
//array of quadwords. In a standard call, this list, if present, must
//be passed at 0(SP).<commit_msg>try custom expanders, doesn't seem to expand yet, so disabled<commit_after>//===- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha --===//
//
//                     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 file defines a pattern matching instruction selector for Alpha.
//
//===----------------------------------------------------------------------===//

#include "Alpha.h"
#include "AlphaRegisterInfo.h"
#include "llvm/Constants.h"                   // FIXME: REMOVE
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include <set>
#include <algorithm>
using namespace llvm;

namespace llvm {
  cl::opt<bool> EnableAlphaIDIV("enable-alpha-intfpdiv",
                             cl::desc("Use the FP div instruction for integer div when possible"),
                             cl::Hidden);
  cl::opt<bool> EnableAlphaFTOI("enable-alpha-FTOI",
                             cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"),
                             cl::Hidden);
  cl::opt<bool> EnableAlphaCT("enable-alpha-CT",
                              cl::desc("Enable use of the ctpop, ctlz, and cttz instructions"),
                              cl::Hidden);
  cl::opt<bool> EnableAlphaCount("enable-alpha-count",
                             cl::desc("Print estimates on live ins and outs"),
                             cl::Hidden);
}

namespace {
  // Alpha Specific DAG Nodes
  namespace AlphaISD {
    enum NodeType {
      // Start the numbering where the builtin ops leave off.
      FIRST_NUMBER = ISD::BUILTIN_OP_END,

      //Convert an int bit pattern in an FP reg to a Double or Float
      //Has a dest type and a source
      CVTQ,
      //Move an Ireg to a FPreg
      ITOF,
      //Move a  FPreg to an Ireg
      FTOI, 
    };
  }
}

//===----------------------------------------------------------------------===//
//  AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
namespace {
  class AlphaTargetLowering : public TargetLowering {
    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
    unsigned GP; //GOT vreg
  public:
    AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
      // Set up the TargetLowering object.
      //I am having problems with shr n ubyte 1
      setShiftAmountType(MVT::i64);
      setSetCCResultType(MVT::i64);
      setSetCCResultContents(ZeroOrOneSetCCResult);

      addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
      addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
      addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass);

      setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
      setOperationAction(ISD::EXTLOAD  , MVT::i1   , Promote);
      setOperationAction(ISD::EXTLOAD  , MVT::f32  , Promote);

      setOperationAction(ISD::ZEXTLOAD , MVT::i1   , Expand);
      setOperationAction(ISD::ZEXTLOAD , MVT::i32  , Expand);

      setOperationAction(ISD::SEXTLOAD , MVT::i1   , Expand);
      setOperationAction(ISD::SEXTLOAD , MVT::i8   , Expand);
      setOperationAction(ISD::SEXTLOAD , MVT::i16  , Expand);

      setOperationAction(ISD::SREM     , MVT::f32  , Expand);
      setOperationAction(ISD::SREM     , MVT::f64  , Expand);

      if (!EnableAlphaCT) {
        setOperationAction(ISD::CTPOP    , MVT::i64  , Expand);
        setOperationAction(ISD::CTTZ     , MVT::i64  , Expand);
        setOperationAction(ISD::CTLZ     , MVT::i64  , Expand);
      }

      //If this didn't legalize into a div....
      //      setOperationAction(ISD::SREM     , MVT::i64, Expand);
      //      setOperationAction(ISD::UREM     , MVT::i64, Expand);

      setOperationAction(ISD::MEMMOVE  , MVT::Other, Expand);
      setOperationAction(ISD::MEMSET   , MVT::Other, Expand);
      setOperationAction(ISD::MEMCPY   , MVT::Other, Expand);

      // We don't support sin/cos/sqrt
      setOperationAction(ISD::FSIN , MVT::f64, Expand);
      setOperationAction(ISD::FCOS , MVT::f64, Expand);
      setOperationAction(ISD::FSQRT, MVT::f64, Expand);
      setOperationAction(ISD::FSIN , MVT::f32, Expand);
      setOperationAction(ISD::FCOS , MVT::f32, Expand);
      setOperationAction(ISD::FSQRT, MVT::f32, Expand);

      //Doesn't work yet
      setOperationAction(ISD::SETCC, MVT::f32,   Promote);

      //Try a couple things with a custom expander
      //setOperationAction(ISD::SINT_TO_FP       , MVT::i64  , Custom);

      computeRegisterProperties();

      addLegalFPImmediate(+0.0); //F31
      addLegalFPImmediate(-0.0); //-F31
    }

    /// LowerOperation - Provide custom lowering hooks for some operations.
    ///
    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);

    /// LowerArguments - This hook must be implemented to indicate how we should
    /// lower the arguments for the specified function, into the specified DAG.
    virtual std::vector<SDOperand>
    LowerArguments(Function &F, SelectionDAG &DAG);

    /// LowerCallTo - This hook lowers an abstract call to a function into an
    /// actual call.
    virtual std::pair<SDOperand, SDOperand>
    LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC,
                bool isTailCall, SDOperand Callee, ArgListTy &Args,
                SelectionDAG &DAG);

    virtual std::pair<SDOperand, SDOperand>
    LowerVAStart(SDOperand Chain, SelectionDAG &DAG);

    virtual std::pair<SDOperand,SDOperand>
    LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
                   const Type *ArgTy, SelectionDAG &DAG);

    virtual std::pair<SDOperand, SDOperand>
    LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
                            SelectionDAG &DAG);

    void restoreGP(MachineBasicBlock* BB)
    {
      BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
    }
  };
}

/// LowerOperation - Provide custom lowering hooks for some operations.
///
SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
    MachineFunction &MF = DAG.getMachineFunction();
    switch (Op.getOpcode()) {
    default: assert(0 && "Should not custom lower this!");
//     case ISD::SINT_TO_FP:
//       {
//         assert (Op.getOperand(0).getValueType() == MVT::i64
//                 && "only quads can be loaded from");
//         SDOperand SRC;
//         if (EnableAlphaFTOI)
//         {
//           std::vector<MVT::ValueType> RTs;
//           RTs.push_back(Op.getValueType());
//           std::vector<SDOperand> Ops;
//           Ops.push_back(Op.getOperand(0));
//           SRC = DAG.getNode(AlphaISD::ITOF, RTs, Ops);
//         } else {
//           int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
//           SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
//           SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
//                                         Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL));
//           SRC = DAG.getLoad(Op.getValueType(), Store.getValue(0), StackSlot,
//                             DAG.getSrcValue(NULL));
//         }
//         std::vector<MVT::ValueType> RTs;
//         RTs.push_back(Op.getValueType());
//         std::vector<SDOperand> Ops;
//         Ops.push_back(SRC);
//         return DAG.getNode(AlphaISD::CVTQ, RTs, Ops);
//       }
    }
}


/// AddLiveIn - This helper function adds the specified physical register to the
/// MachineFunction as a live in value.  It also creates a corresponding virtual
/// register for it.
static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
                          TargetRegisterClass *RC) {
  assert(RC->contains(PReg) && "Not the correct regclass!");
  unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
  MF.addLiveIn(PReg, VReg);
  return VReg;
}

//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21

//For now, just use variable size stack frame format

//In a standard call, the first six items are passed in registers $16
//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
//of argument-to-register correspondence.) The remaining items are
//collected in a memory argument list that is a naturally aligned
//array of quadwords. In a standard call, this list, if present, must
//be passed at 0(SP).
{'fraction_non_alphanumeric': 0.1470514271344147, 'fraction_numerical': 0.010499182698352823, 'mean_word_length': 2.5786276715410574, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3613842', 'n_tokens_mistral': 4815, 'n_tokens_neox': 4835, 'n_words': 1175}