//===-- 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 "PTXInstrInfo.h"
#include "PTX.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) && MI->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::iterator iter = MBB.end();
  const MachineInstr& instLast1 = *--iter;
  // 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;

  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 (instLast1.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 (instLast1.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 (instLast2.isConditionalBranch() &&
      instLast1.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 {
  llvm_unreachable("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 {
  llvm_unreachable("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) {
  return inst.isTerminator() || inst.isBranch() || inst.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();
}
