//===- PTXInstrInfo.cpp - PTX Instruction Information ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the PTX implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "ptx-instrinfo"

#include "PTX.h"
#include "PTXInstrInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"

#define GET_INSTRINFO_CTOR
#include "PTXGenInstrInfo.inc"

using namespace llvm;

PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
  : PTXGenInstrInfo(),
    RI(_TM, *this), TM(_TM) {}

static const struct map_entry {
  const TargetRegisterClass *cls;
  const int opcode;
} map[] = {
  { &PTX::RegI16RegClass, PTX::MOVU16rr },
  { &PTX::RegI32RegClass, PTX::MOVU32rr },
  { &PTX::RegI64RegClass, PTX::MOVU64rr },
  { &PTX::RegF32RegClass, PTX::MOVF32rr },
  { &PTX::RegF64RegClass, PTX::MOVF64rr },
  { &PTX::RegPredRegClass,   PTX::MOVPREDrr }
};

void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator I, DebugLoc DL,
                               unsigned DstReg, unsigned SrcReg,
                               bool KillSrc) const {

  const MachineRegisterInfo& MRI = MBB.getParent()->getRegInfo();
  //assert(MRI.getRegClass(SrcReg) == MRI.getRegClass(DstReg) &&
  //  "Invalid register copy between two register classes");

  for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++i) {
    if (map[i].cls == MRI.getRegClass(DstReg)) {
      const MCInstrDesc &MCID = get(map[i].opcode);
      MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).
        addReg(SrcReg, getKillRegState(KillSrc));
      AddDefaultPredicate(MI);
      return;
    }
  }

  llvm_unreachable("Impossible reg-to-reg copy");
}

bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
                                MachineBasicBlock::iterator I,
                                unsigned DstReg, unsigned SrcReg,
                                const TargetRegisterClass *DstRC,
                                const TargetRegisterClass *SrcRC,
                                DebugLoc DL) const {
  if (DstRC != SrcRC)
    return false;

  for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
    if (DstRC == map[i].cls) {
      const MCInstrDesc &MCID = get(map[i].opcode);
      MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).addReg(SrcReg);
      AddDefaultPredicate(MI);
      return true;
    }

  return false;
}

bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
                               unsigned &SrcReg, unsigned &DstReg,
                               unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
  switch (MI.getOpcode()) {
    default:
      return false;
    case PTX::MOVU16rr:
    case PTX::MOVU32rr:
    case PTX::MOVU64rr:
    case PTX::MOVF32rr:
    case PTX::MOVF64rr:
    case PTX::MOVPREDrr:
      assert(MI.getNumOperands() >= 2 &&
             MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
             "Invalid register-register move instruction");
      SrcSubIdx = DstSubIdx = 0; // No sub-registers
      DstReg = MI.getOperand(0).getReg();
      SrcReg = MI.getOperand(1).getReg();
      return true;
  }
}

// predicate support

bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
  int i = MI->findFirstPredOperandIdx();
  return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
}

bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
  return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
}

bool PTXInstrInfo::
PredicateInstruction(MachineInstr *MI,
                     const SmallVectorImpl<MachineOperand> &Pred) const {
  if (Pred.size() < 2)
    llvm_unreachable("lesser than 2 predicate operands are provided");

  int i = MI->findFirstPredOperandIdx();
  if (i == -1)
    llvm_unreachable("missing predicate operand");

  MI->getOperand(i).setReg(Pred[0].getReg());
  MI->getOperand(i+1).setImm(Pred[1].getImm());

  return true;
}

bool PTXInstrInfo::
SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
                  const SmallVectorImpl<MachineOperand> &Pred2) const {
  const MachineOperand &PredReg1 = Pred1[0];
  const MachineOperand &PredReg2 = Pred2[0];
  if (PredReg1.getReg() != PredReg2.getReg())
    return false;

  const MachineOperand &PredOp1 = Pred1[1];
  const MachineOperand &PredOp2 = Pred2[1];
  if (PredOp1.getImm() != PredOp2.getImm())
    return false;

  return true;
}

bool PTXInstrInfo::
DefinesPredicate(MachineInstr *MI,
                 std::vector<MachineOperand> &Pred) const {
  // If an instruction sets a predicate register, it defines a predicate.

  // TODO supprot 5-operand format of setp instruction

  if (MI->getNumOperands() < 1)
    return false;

  const MachineOperand &MO = MI->getOperand(0);

  if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::RegPredRegClass)
    return false;

  Pred.push_back(MO);
  Pred.push_back(MachineOperand::CreateImm(PTXPredicate::None));
  return true;
}

// branch support

bool PTXInstrInfo::
AnalyzeBranch(MachineBasicBlock &MBB,
              MachineBasicBlock *&TBB,
              MachineBasicBlock *&FBB,
              SmallVectorImpl<MachineOperand> &Cond,
              bool AllowModify) const {
  // TODO implement cases when AllowModify is true

  if (MBB.empty())
    return true;

  MachineBasicBlock::const_iterator iter = MBB.end();
  const MachineInstr& instLast1 = *--iter;
  const MCInstrDesc &desc1 = instLast1.getDesc();
  // for special case that MBB has only 1 instruction
  const bool IsSizeOne = MBB.size() == 1;
  // if IsSizeOne is true, *--iter and instLast2 are invalid
  // we put a dummy value in instLast2 and desc2 since they are used
  const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter;
  const MCInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();

  DEBUG(dbgs() << "\n");
  DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n");
  DEBUG(dbgs() << "AnalyzeBranch: MBB:    " << MBB.getName().str() << "\n");
  DEBUG(dbgs() << "AnalyzeBranch: TBB:    " << TBB << "\n");
  DEBUG(dbgs() << "AnalyzeBranch: FBB:    " << FBB << "\n");

  // this block ends with no branches
  if (!IsAnyKindOfBranch(instLast1)) {
    DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n");
    return false;
  }

  // this block ends with only an unconditional branch
  if (desc1.isUnconditionalBranch() &&
      // when IsSizeOne is true, it "absorbs" the evaluation of instLast2
      (IsSizeOne || !IsAnyKindOfBranch(instLast2))) {
    DEBUG(dbgs() << "AnalyzeBranch: ends with only uncond branch\n");
    TBB = GetBranchTarget(instLast1);
    return false;
  }

  // this block ends with a conditional branch and
  // it falls through to a successor block
  if (desc1.isConditionalBranch() &&
      IsAnySuccessorAlsoLayoutSuccessor(MBB)) {
    DEBUG(dbgs() << "AnalyzeBranch: ends with cond branch and fall through\n");
    TBB = GetBranchTarget(instLast1);
    int i = instLast1.findFirstPredOperandIdx();
    Cond.push_back(instLast1.getOperand(i));
    Cond.push_back(instLast1.getOperand(i+1));
    return false;
  }

  // when IsSizeOne is true, we are done
  if (IsSizeOne)
    return true;

  // this block ends with a conditional branch
  // followed by an unconditional branch
  if (desc2.isConditionalBranch() &&
      desc1.isUnconditionalBranch()) {
    DEBUG(dbgs() << "AnalyzeBranch: ends with cond and uncond branch\n");
    TBB = GetBranchTarget(instLast2);
    FBB = GetBranchTarget(instLast1);
    int i = instLast2.findFirstPredOperandIdx();
    Cond.push_back(instLast2.getOperand(i));
    Cond.push_back(instLast2.getOperand(i+1));
    return false;
  }

  // branch cannot be understood
  DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
  return true;
}

unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
  unsigned count = 0;
  while (!MBB.empty())
    if (IsAnyKindOfBranch(MBB.back())) {
      MBB.pop_back();
      ++count;
    } else
      break;
  DEBUG(dbgs() << "RemoveBranch: MBB:   " << MBB.getName().str() << "\n");
  DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
  return count;
}

unsigned PTXInstrInfo::
InsertBranch(MachineBasicBlock &MBB,
             MachineBasicBlock *TBB,
             MachineBasicBlock *FBB,
             const SmallVectorImpl<MachineOperand> &Cond,
             DebugLoc DL) const {
  DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
  DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
                        << "\n";
        else     dbgs() << "InsertBranch: TBB: (NULL)\n");
  DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
                        << "\n";
        else     dbgs() << "InsertBranch: FBB: (NULL)\n");
  DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");

  assert(TBB && "TBB is NULL");

  if (FBB) {
    BuildMI(&MBB, DL, get(PTX::BRAdp))
      .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
    BuildMI(&MBB, DL, get(PTX::BRAd))
      .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTXPredicate::None);
    return 2;
  } else if (Cond.size()) {
    BuildMI(&MBB, DL, get(PTX::BRAdp))
      .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
    return 1;
  } else {
    BuildMI(&MBB, DL, get(PTX::BRAd))
      .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTXPredicate::None);
    return 1;
  }
}

// Memory operand folding for spills
void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                       MachineBasicBlock::iterator MII,
                                     unsigned SrcReg, bool isKill, int FrameIdx,
                                       const TargetRegisterClass *RC,
                                       const TargetRegisterInfo *TRI) const {
  assert(false && "storeRegToStackSlot should not be called for PTX");
}

void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                        MachineBasicBlock::iterator MII,
                                        unsigned DestReg, int FrameIdx,
                                        const TargetRegisterClass *RC,
                                        const TargetRegisterInfo *TRI) const {
  assert(false && "loadRegFromStackSlot should not be called for PTX");
}

// static helper routines

MachineSDNode *PTXInstrInfo::
GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
                  DebugLoc dl, EVT VT, SDValue Op1) {
  SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
  SDValue predOp = DAG->getTargetConstant(PTXPredicate::None, MVT::i32);
  SDValue ops[] = { Op1, predReg, predOp };
  return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
}

MachineSDNode *PTXInstrInfo::
GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
                  DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
  SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
  SDValue predOp = DAG->getTargetConstant(PTXPredicate::None, MVT::i32);
  SDValue ops[] = { Op1, Op2, predReg, predOp };
  return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
}

void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
  if (MI->findFirstPredOperandIdx() == -1) {
    MI->addOperand(MachineOperand::CreateReg(PTX::NoRegister, /*IsDef=*/false));
    MI->addOperand(MachineOperand::CreateImm(PTXPredicate::None));
  }
}

bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
  const MCInstrDesc &desc = inst.getDesc();
  return desc.isTerminator() || desc.isBranch() || desc.isIndirectBranch();
}

bool PTXInstrInfo::
IsAnySuccessorAlsoLayoutSuccessor(const MachineBasicBlock& MBB) {
  for (MachineBasicBlock::const_succ_iterator
      i = MBB.succ_begin(), e = MBB.succ_end(); i != e; ++i)
    if (MBB.isLayoutSuccessor((const MachineBasicBlock*) &*i))
      return true;
  return false;
}

MachineBasicBlock *PTXInstrInfo::GetBranchTarget(const MachineInstr& inst) {
  // FIXME So far all branch instructions put destination in 1st operand
  const MachineOperand& target = inst.getOperand(0);
  assert(target.isMBB() && "FIXME: detect branch target operand");
  return target.getMBB();
}
