//===- ExecutionDepsFix.cpp - Fix execution dependecy issues ----*- C++ -*-===//
//
//                     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 execution dependency fix pass.
//
// Some X86 SSE instructions like mov, and, or, xor are available in different
// variants for different operand types. These variant instructions are
// equivalent, but on Nehalem and newer cpus there is extra latency
// transferring data between integer and floating point domains.  ARM cores
// have similar issues when they are configured with both VFP and NEON
// pipelines.
//
// This pass changes the variant instructions to minimize domain crossings.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "execution-fix"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

/// A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track
/// of execution domains.
///
/// An open DomainValue represents a set of instructions that can still switch
/// execution domain. Multiple registers may refer to the same open
/// DomainValue - they will eventually be collapsed to the same execution
/// domain.
///
/// A collapsed DomainValue represents a single register that has been forced
/// into one of more execution domains. There is a separate collapsed
/// DomainValue for each register, but it may contain multiple execution
/// domains. A register value is initially created in a single execution
/// domain, but if we were forced to pay the penalty of a domain crossing, we
/// keep track of the fact the the register is now available in multiple
/// domains.
namespace {
struct DomainValue {
  // Basic reference counting.
  unsigned Refs;

  // Bitmask of available domains. For an open DomainValue, it is the still
  // possible domains for collapsing. For a collapsed DomainValue it is the
  // domains where the register is available for free.
  unsigned AvailableDomains;

  // Position of the last defining instruction.
  unsigned Dist;

  // Twiddleable instructions using or defining these registers.
  SmallVector<MachineInstr*, 8> Instrs;

  // A collapsed DomainValue has no instructions to twiddle - it simply keeps
  // track of the domains where the registers are already available.
  bool isCollapsed() const { return Instrs.empty(); }

  // Is domain available?
  bool hasDomain(unsigned domain) const {
    return AvailableDomains & (1u << domain);
  }

  // Mark domain as available.
  void addDomain(unsigned domain) {
    AvailableDomains |= 1u << domain;
  }

  // Restrict to a single domain available.
  void setSingleDomain(unsigned domain) {
    AvailableDomains = 1u << domain;
  }

  // Return bitmask of domains that are available and in mask.
  unsigned getCommonDomains(unsigned mask) const {
    return AvailableDomains & mask;
  }

  // First domain available.
  unsigned getFirstDomain() const {
    return CountTrailingZeros_32(AvailableDomains);
  }

  DomainValue() { clear(); }

  void clear() {
    Refs = AvailableDomains = Dist = 0;
    Instrs.clear();
  }
};
}

namespace {
class ExeDepsFix : public MachineFunctionPass {
  static char ID;
  SpecificBumpPtrAllocator<DomainValue> Allocator;
  SmallVector<DomainValue*,16> Avail;

  const TargetRegisterClass *const RC;
  MachineFunction *MF;
  const TargetInstrInfo *TII;
  const TargetRegisterInfo *TRI;
  MachineBasicBlock *MBB;
  std::vector<int> AliasMap;
  const unsigned NumRegs;
  DomainValue **LiveRegs;
  typedef DenseMap<MachineBasicBlock*,DomainValue**> LiveOutMap;
  LiveOutMap LiveOuts;
  unsigned Distance;

public:
  ExeDepsFix(const TargetRegisterClass *rc)
    : MachineFunctionPass(ID), RC(rc), NumRegs(RC->getNumRegs()) {}

  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    AU.setPreservesAll();
    MachineFunctionPass::getAnalysisUsage(AU);
  }

  virtual bool runOnMachineFunction(MachineFunction &MF);

  virtual const char *getPassName() const {
    return "SSE execution domain fixup";
  }

private:
  // Register mapping.
  int RegIndex(unsigned Reg);

  // DomainValue allocation.
  DomainValue *Alloc(int domain = -1);
  void Recycle(DomainValue*);

  // LiveRegs manipulations.
  void SetLiveReg(int rx, DomainValue *DV);
  void Kill(int rx);
  void Force(int rx, unsigned domain);
  void Collapse(DomainValue *dv, unsigned domain);
  bool Merge(DomainValue *A, DomainValue *B);

  void enterBasicBlock();
  void visitGenericInstr(MachineInstr*);
  void visitSoftInstr(MachineInstr*, unsigned mask);
  void visitHardInstr(MachineInstr*, unsigned domain);
};
}

char ExeDepsFix::ID = 0;

/// Translate TRI register number to an index into our smaller tables of
/// interesting registers. Return -1 for boring registers.
int ExeDepsFix::RegIndex(unsigned Reg) {
  assert(Reg < AliasMap.size() && "Invalid register");
  return AliasMap[Reg];
}

DomainValue *ExeDepsFix::Alloc(int domain) {
  DomainValue *dv = Avail.empty() ?
                      new(Allocator.Allocate()) DomainValue :
                      Avail.pop_back_val();
  dv->Dist = Distance;
  if (domain >= 0)
    dv->addDomain(domain);
  return dv;
}

void ExeDepsFix::Recycle(DomainValue *dv) {
  assert(dv && "Cannot recycle NULL");
  dv->clear();
  Avail.push_back(dv);
}

/// Set LiveRegs[rx] = dv, updating reference counts.
void ExeDepsFix::SetLiveReg(int rx, DomainValue *dv) {
  assert(unsigned(rx) < NumRegs && "Invalid index");
  if (!LiveRegs) {
    LiveRegs = new DomainValue*[NumRegs];
    std::fill(LiveRegs, LiveRegs+NumRegs, (DomainValue*)0);
  }

  if (LiveRegs[rx] == dv)
    return;
  if (LiveRegs[rx]) {
    assert(LiveRegs[rx]->Refs && "Bad refcount");
    if (--LiveRegs[rx]->Refs == 0) Recycle(LiveRegs[rx]);
  }
  LiveRegs[rx] = dv;
  if (dv) ++dv->Refs;
}

// Kill register rx, recycle or collapse any DomainValue.
void ExeDepsFix::Kill(int rx) {
  assert(unsigned(rx) < NumRegs && "Invalid index");
  if (!LiveRegs || !LiveRegs[rx]) return;

  // Before killing the last reference to an open DomainValue, collapse it to
  // the first available domain.
  if (LiveRegs[rx]->Refs == 1 && !LiveRegs[rx]->isCollapsed())
    Collapse(LiveRegs[rx], LiveRegs[rx]->getFirstDomain());
  else
    SetLiveReg(rx, 0);
}

/// Force register rx into domain.
void ExeDepsFix::Force(int rx, unsigned domain) {
  assert(unsigned(rx) < NumRegs && "Invalid index");
  DomainValue *dv;
  if (LiveRegs && (dv = LiveRegs[rx])) {
    if (dv->isCollapsed())
      dv->addDomain(domain);
    else if (dv->hasDomain(domain))
      Collapse(dv, domain);
    else {
      // This is an incompatible open DomainValue. Collapse it to whatever and
      // force the new value into domain. This costs a domain crossing.
      Collapse(dv, dv->getFirstDomain());
      assert(LiveRegs[rx] && "Not live after collapse?");
      LiveRegs[rx]->addDomain(domain);
    }
  } else {
    // Set up basic collapsed DomainValue.
    SetLiveReg(rx, Alloc(domain));
  }
}

/// Collapse open DomainValue into given domain. If there are multiple
/// registers using dv, they each get a unique collapsed DomainValue.
void ExeDepsFix::Collapse(DomainValue *dv, unsigned domain) {
  assert(dv->hasDomain(domain) && "Cannot collapse");

  // Collapse all the instructions.
  while (!dv->Instrs.empty())
    TII->setExecutionDomain(dv->Instrs.pop_back_val(), domain);
  dv->setSingleDomain(domain);

  // If there are multiple users, give them new, unique DomainValues.
  if (LiveRegs && dv->Refs > 1)
    for (unsigned rx = 0; rx != NumRegs; ++rx)
      if (LiveRegs[rx] == dv)
        SetLiveReg(rx, Alloc(domain));
}

/// Merge - All instructions and registers in B are moved to A, and B is
/// released.
bool ExeDepsFix::Merge(DomainValue *A, DomainValue *B) {
  assert(!A->isCollapsed() && "Cannot merge into collapsed");
  assert(!B->isCollapsed() && "Cannot merge from collapsed");
  if (A == B)
    return true;
  // Restrict to the domains that A and B have in common.
  unsigned common = A->getCommonDomains(B->AvailableDomains);
  if (!common)
    return false;
  A->AvailableDomains = common;
  A->Dist = std::max(A->Dist, B->Dist);
  A->Instrs.append(B->Instrs.begin(), B->Instrs.end());
  for (unsigned rx = 0; rx != NumRegs; ++rx)
    if (LiveRegs[rx] == B)
      SetLiveReg(rx, A);
  return true;
}

void ExeDepsFix::enterBasicBlock() {
  // Try to coalesce live-out registers from predecessors.
  for (MachineBasicBlock::livein_iterator i = MBB->livein_begin(),
         e = MBB->livein_end(); i != e; ++i) {
    int rx = RegIndex(*i);
    if (rx < 0) continue;
    for (MachineBasicBlock::const_pred_iterator pi = MBB->pred_begin(),
           pe = MBB->pred_end(); pi != pe; ++pi) {
      LiveOutMap::const_iterator fi = LiveOuts.find(*pi);
      if (fi == LiveOuts.end()) continue;
      DomainValue *pdv = fi->second[rx];
      if (!pdv) continue;
      if (!LiveRegs || !LiveRegs[rx]) {
        SetLiveReg(rx, pdv);
        continue;
      }

      // We have a live DomainValue from more than one predecessor.
      if (LiveRegs[rx]->isCollapsed()) {
        // We are already collapsed, but predecessor is not. Force him.
        unsigned domain = LiveRegs[rx]->getFirstDomain();
        if (!pdv->isCollapsed() && pdv->hasDomain(domain))
          Collapse(pdv, domain);
        continue;
      }

      // Currently open, merge in predecessor.
      if (!pdv->isCollapsed())
        Merge(LiveRegs[rx], pdv);
      else
        Force(rx, pdv->getFirstDomain());
    }
  }
}

// A hard instruction only works in one domain. All input registers will be
// forced into that domain.
void ExeDepsFix::visitHardInstr(MachineInstr *mi, unsigned domain) {
  // Collapse all uses.
  for (unsigned i = mi->getDesc().getNumDefs(),
                e = mi->getDesc().getNumOperands(); i != e; ++i) {
    MachineOperand &mo = mi->getOperand(i);
    if (!mo.isReg()) continue;
    int rx = RegIndex(mo.getReg());
    if (rx < 0) continue;
    Force(rx, domain);
  }

  // Kill all defs and force them.
  for (unsigned i = 0, e = mi->getDesc().getNumDefs(); i != e; ++i) {
    MachineOperand &mo = mi->getOperand(i);
    if (!mo.isReg()) continue;
    int rx = RegIndex(mo.getReg());
    if (rx < 0) continue;
    Kill(rx);
    Force(rx, domain);
  }
}

// A soft instruction can be changed to work in other domains given by mask.
void ExeDepsFix::visitSoftInstr(MachineInstr *mi, unsigned mask) {
  // Bitmask of available domains for this instruction after taking collapsed
  // operands into account.
  unsigned available = mask;

  // Scan the explicit use operands for incoming domains.
  SmallVector<int, 4> used;
  if (LiveRegs)
    for (unsigned i = mi->getDesc().getNumDefs(),
                  e = mi->getDesc().getNumOperands(); i != e; ++i) {
      MachineOperand &mo = mi->getOperand(i);
      if (!mo.isReg()) continue;
      int rx = RegIndex(mo.getReg());
      if (rx < 0) continue;
      if (DomainValue *dv = LiveRegs[rx]) {
        // Bitmask of domains that dv and available have in common.
        unsigned common = dv->getCommonDomains(available);
        // Is it possible to use this collapsed register for free?
        if (dv->isCollapsed()) {
          // Restrict available domains to the ones in common with the operand.
          // If there are no common domains, we must pay the cross-domain 
          // penalty for this operand.
          if (common) available = common;
        } else if (common)
          // Open DomainValue is compatible, save it for merging.
          used.push_back(rx);
        else
          // Open DomainValue is not compatible with instruction. It is useless
          // now.
          Kill(rx);
      }
    }

  // If the collapsed operands force a single domain, propagate the collapse.
  if (isPowerOf2_32(available)) {
    unsigned domain = CountTrailingZeros_32(available);
    TII->setExecutionDomain(mi, domain);
    visitHardInstr(mi, domain);
    return;
  }

  // Kill off any remaining uses that don't match available, and build a list of
  // incoming DomainValues that we want to merge.
  SmallVector<DomainValue*,4> doms;
  for (SmallVector<int, 4>::iterator i=used.begin(), e=used.end(); i!=e; ++i) {
    int rx = *i;
    DomainValue *dv = LiveRegs[rx];
    // This useless DomainValue could have been missed above.
    if (!dv->getCommonDomains(available)) {
      Kill(*i);
      continue;
    }
    // sorted, uniqued insert.
    bool inserted = false;
    for (SmallVector<DomainValue*,4>::iterator i = doms.begin(), e = doms.end();
           i != e && !inserted; ++i) {
      if (dv == *i)
        inserted = true;
      else if (dv->Dist < (*i)->Dist) {
        inserted = true;
        doms.insert(i, dv);
      }
    }
    if (!inserted)
      doms.push_back(dv);
  }

  // doms are now sorted in order of appearance. Try to merge them all, giving
  // priority to the latest ones.
  DomainValue *dv = 0;
  while (!doms.empty()) {
    if (!dv) {
      dv = doms.pop_back_val();
      continue;
    }

    DomainValue *latest = doms.pop_back_val();
    if (Merge(dv, latest)) continue;

    // If latest didn't merge, it is useless now. Kill all registers using it.
    for (SmallVector<int,4>::iterator i=used.begin(), e=used.end(); i != e; ++i)
      if (LiveRegs[*i] == latest)
        Kill(*i);
  }

  // dv is the DomainValue we are going to use for this instruction.
  if (!dv)
    dv = Alloc();
  dv->Dist = Distance;
  dv->AvailableDomains = available;
  dv->Instrs.push_back(mi);

  // Finally set all defs and non-collapsed uses to dv.
  for (unsigned i = 0, e = mi->getDesc().getNumOperands(); i != e; ++i) {
    MachineOperand &mo = mi->getOperand(i);
    if (!mo.isReg()) continue;
    int rx = RegIndex(mo.getReg());
    if (rx < 0) continue;
    if (!LiveRegs || !LiveRegs[rx] || (mo.isDef() && LiveRegs[rx]!=dv)) {
      Kill(rx);
      SetLiveReg(rx, dv);
    }
  }
}

void ExeDepsFix::visitGenericInstr(MachineInstr *mi) {
  // Process explicit defs, kill any relevant registers redefined.
  for (unsigned i = 0, e = mi->getDesc().getNumDefs(); i != e; ++i) {
    MachineOperand &mo = mi->getOperand(i);
    if (!mo.isReg()) continue;
    int rx = RegIndex(mo.getReg());
    if (rx < 0) continue;
    Kill(rx);
  }
}

bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) {
  MF = &mf;
  TII = MF->getTarget().getInstrInfo();
  TRI = MF->getTarget().getRegisterInfo();
  MBB = 0;
  LiveRegs = 0;
  Distance = 0;
  assert(NumRegs == RC->getNumRegs() && "Bad regclass");

  // If no relevant registers are used in the function, we can skip it
  // completely.
  bool anyregs = false;
  for (TargetRegisterClass::const_iterator I = RC->begin(), E = RC->end();
       I != E; ++I)
    if (MF->getRegInfo().isPhysRegUsed(*I)) {
      anyregs = true;
      break;
    }
  if (!anyregs) return false;

  // Initialize the AliasMap on the first use.
  if (AliasMap.empty()) {
    // Given a PhysReg, AliasMap[PhysReg] is either the relevant index into RC,
    // or -1.
    AliasMap.resize(TRI->getNumRegs(), -1);
    for (unsigned i = 0, e = RC->getNumRegs(); i != e; ++i)
      for (const unsigned *AI = TRI->getOverlaps(RC->getRegister(i)); *AI; ++AI)
        AliasMap[*AI] = i;
  }

  MachineBasicBlock *Entry = MF->begin();
  SmallPtrSet<MachineBasicBlock*, 16> Visited;
  for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*, 16> >
         DFI = df_ext_begin(Entry, Visited), DFE = df_ext_end(Entry, Visited);
         DFI != DFE; ++DFI) {
    MBB = *DFI;
    enterBasicBlock();
    for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
        ++I) {
      MachineInstr *mi = I;
      if (mi->isDebugValue()) continue;
      ++Distance;
      std::pair<uint16_t, uint16_t> domp = TII->getExecutionDomain(mi);
      if (domp.first)
        if (domp.second)
          visitSoftInstr(mi, domp.second);
        else
          visitHardInstr(mi, domp.first);
      else if (LiveRegs)
        visitGenericInstr(mi);
    }

    // Save live registers at end of MBB - used by enterBasicBlock().
    if (LiveRegs)
      LiveOuts.insert(std::make_pair(MBB, LiveRegs));
    LiveRegs = 0;
  }

  // Clear the LiveOuts vectors. Should we also collapse any remaining
  // DomainValues?
  for (LiveOutMap::const_iterator i = LiveOuts.begin(), e = LiveOuts.end();
         i != e; ++i)
    delete[] i->second;
  LiveOuts.clear();
  Avail.clear();
  Allocator.DestroyAll();

  return false;
}

FunctionPass *
llvm::createExecutionDependencyFixPass(const TargetRegisterClass *RC) {
  return new ExeDepsFix(RC);
}
