//===- SetTheory.cpp - Generate ordered sets from DAG expressions ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the SetTheory class that computes ordered sets of
// Records from DAG expressions.
//
//===----------------------------------------------------------------------===//

#include "SetTheory.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/Support/Format.h"

using namespace llvm;

// Define the standard operators.
namespace {

typedef SetTheory::RecSet RecSet;
typedef SetTheory::RecVec RecVec;

// (add a, b, ...) Evaluate and union all arguments.
struct AddOp : public SetTheory::Operator {
  void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
    ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts);
  }
};

// (sub Add, Sub, ...) Set difference.
struct SubOp : public SetTheory::Operator {
  void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
    if (Expr->arg_size() < 2)
      throw "Set difference needs at least two arguments: " +
        Expr->getAsString();
    RecSet Add, Sub;
    ST.evaluate(*Expr->arg_begin(), Add);
    ST.evaluate(Expr->arg_begin() + 1, Expr->arg_end(), Sub);
    for (RecSet::iterator I = Add.begin(), E = Add.end(); I != E; ++I)
      if (!Sub.count(*I))
        Elts.insert(*I);
  }
};

// (and S1, S2) Set intersection.
struct AndOp : public SetTheory::Operator {
  void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
    if (Expr->arg_size() != 2)
      throw "Set intersection requires two arguments: " + Expr->getAsString();
    RecSet S1, S2;
    ST.evaluate(Expr->arg_begin()[0], S1);
    ST.evaluate(Expr->arg_begin()[1], S2);
    for (RecSet::iterator I = S1.begin(), E = S1.end(); I != E; ++I)
      if (S2.count(*I))
        Elts.insert(*I);
  }
};

// SetIntBinOp - Abstract base class for (Op S, N) operators.
struct SetIntBinOp : public SetTheory::Operator {
  virtual void apply2(SetTheory &ST, DagInit *Expr,
                     RecSet &Set, int64_t N,
                     RecSet &Elts) =0;

  void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
    if (Expr->arg_size() != 2)
      throw "Operator requires (Op Set, Int) arguments: " + Expr->getAsString();
    RecSet Set;
    ST.evaluate(Expr->arg_begin()[0], Set);
    IntInit *II = dynamic_cast<IntInit*>(Expr->arg_begin()[1]);
    if (!II)
      throw "Second argument must be an integer: " + Expr->getAsString();
    apply2(ST, Expr, Set, II->getValue(), Elts);
  }
};

// (shl S, N) Shift left, remove the first N elements.
struct ShlOp : public SetIntBinOp {
  void apply2(SetTheory &ST, DagInit *Expr,
             RecSet &Set, int64_t N,
             RecSet &Elts) {
    if (N < 0)
      throw "Positive shift required: " + Expr->getAsString();
    if (unsigned(N) < Set.size())
      Elts.insert(Set.begin() + N, Set.end());
  }
};

// (trunc S, N) Truncate after the first N elements.
struct TruncOp : public SetIntBinOp {
  void apply2(SetTheory &ST, DagInit *Expr,
             RecSet &Set, int64_t N,
             RecSet &Elts) {
    if (N < 0)
      throw "Positive length required: " + Expr->getAsString();
    if (unsigned(N) > Set.size())
      N = Set.size();
    Elts.insert(Set.begin(), Set.begin() + N);
  }
};

// Left/right rotation.
struct RotOp : public SetIntBinOp {
  const bool Reverse;

  RotOp(bool Rev) : Reverse(Rev) {}

  void apply2(SetTheory &ST, DagInit *Expr,
             RecSet &Set, int64_t N,
             RecSet &Elts) {
    if (Reverse)
      N = -N;
    // N > 0 -> rotate left, N < 0 -> rotate right.
    if (Set.empty())
      return;
    if (N < 0)
      N = Set.size() - (-N % Set.size());
    else
      N %= Set.size();
    Elts.insert(Set.begin() + N, Set.end());
    Elts.insert(Set.begin(), Set.begin() + N);
  }
};

// (decimate S, N) Pick every N'th element of S.
struct DecimateOp : public SetIntBinOp {
  void apply2(SetTheory &ST, DagInit *Expr,
             RecSet &Set, int64_t N,
             RecSet &Elts) {
    if (N <= 0)
      throw "Positive stride required: " + Expr->getAsString();
    for (unsigned I = 0; I < Set.size(); I += N)
      Elts.insert(Set[I]);
  }
};

// (interleave S1, S2, ...) Interleave elements of the arguments.
struct InterleaveOp : public SetTheory::Operator {
  void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
    // Evaluate the arguments individually.
    SmallVector<RecSet, 4> Args(Expr->getNumArgs());
    unsigned MaxSize = 0;
    for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i) {
      ST.evaluate(Expr->getArg(i), Args[i]);
      MaxSize = std::max(MaxSize, unsigned(Args[i].size()));
    }
    // Interleave arguments into Elts.
    for (unsigned n = 0; n != MaxSize; ++n)
      for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i)
        if (n < Args[i].size())
          Elts.insert(Args[i][n]);
  }
};

// (sequence "Format", From, To) Generate a sequence of records by name.
struct SequenceOp : public SetTheory::Operator {
  void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
    int Step = 1;
    if (Expr->arg_size() > 4)
      throw "Bad args to (sequence \"Format\", From, To): " +
        Expr->getAsString();
    else if (Expr->arg_size() == 4) {
      if (IntInit *II = dynamic_cast<IntInit*>(Expr->arg_begin()[3])) {
        Step = II->getValue();
      } else
        throw "Stride must be an integer: " + Expr->getAsString();
    }

    std::string Format;
    if (StringInit *SI = dynamic_cast<StringInit*>(Expr->arg_begin()[0]))
      Format = SI->getValue();
    else
      throw "Format must be a string: " + Expr->getAsString();

    int64_t From, To;
    if (IntInit *II = dynamic_cast<IntInit*>(Expr->arg_begin()[1]))
      From = II->getValue();
    else
      throw "From must be an integer: " + Expr->getAsString();
    if (From < 0 || From >= (1 << 30))
      throw "From out of range";

    if (IntInit *II = dynamic_cast<IntInit*>(Expr->arg_begin()[2]))
      To = II->getValue();
    else
      throw "From must be an integer: " + Expr->getAsString();
    if (To < 0 || To >= (1 << 30))
      throw "To out of range";

    RecordKeeper &Records =
      dynamic_cast<DefInit&>(*Expr->getOperator()).getDef()->getRecords();

    Step *= From <= To ? 1 : -1;
    while (true) {
      if (Step > 0 && From > To)
        break;
      else if (Step < 0 && From < To)
        break;
      std::string Name;
      raw_string_ostream OS(Name);
      OS << format(Format.c_str(), unsigned(From));
      Record *Rec = Records.getDef(OS.str());
      if (!Rec)
        throw "No def named '" + Name + "': " + Expr->getAsString();
      // Try to reevaluate Rec in case it is a set.
      if (const RecVec *Result = ST.expand(Rec))
        Elts.insert(Result->begin(), Result->end());
      else
        Elts.insert(Rec);

      From += Step;
    }
  }
};

// Expand a Def into a set by evaluating one of its fields.
struct FieldExpander : public SetTheory::Expander {
  StringRef FieldName;

  FieldExpander(StringRef fn) : FieldName(fn) {}

  void expand(SetTheory &ST, Record *Def, RecSet &Elts) {
    ST.evaluate(Def->getValueInit(FieldName), Elts);
  }
};
} // end anonymous namespace

void SetTheory::Operator::anchor() { }

void SetTheory::Expander::anchor() { }

SetTheory::SetTheory() {
  addOperator("add", new AddOp);
  addOperator("sub", new SubOp);
  addOperator("and", new AndOp);
  addOperator("shl", new ShlOp);
  addOperator("trunc", new TruncOp);
  addOperator("rotl", new RotOp(false));
  addOperator("rotr", new RotOp(true));
  addOperator("decimate", new DecimateOp);
  addOperator("interleave", new InterleaveOp);
  addOperator("sequence", new SequenceOp);
}

void SetTheory::addOperator(StringRef Name, Operator *Op) {
  Operators[Name] = Op;
}

void SetTheory::addExpander(StringRef ClassName, Expander *E) {
  Expanders[ClassName] = E;
}

void SetTheory::addFieldExpander(StringRef ClassName, StringRef FieldName) {
  addExpander(ClassName, new FieldExpander(FieldName));
}

void SetTheory::evaluate(Init *Expr, RecSet &Elts) {
  // A def in a list can be a just an element, or it may expand.
  if (DefInit *Def = dynamic_cast<DefInit*>(Expr)) {
    if (const RecVec *Result = expand(Def->getDef()))
      return Elts.insert(Result->begin(), Result->end());
    Elts.insert(Def->getDef());
    return;
  }

  // Lists simply expand.
  if (ListInit *LI = dynamic_cast<ListInit*>(Expr))
    return evaluate(LI->begin(), LI->end(), Elts);

  // Anything else must be a DAG.
  DagInit *DagExpr = dynamic_cast<DagInit*>(Expr);
  if (!DagExpr)
    throw "Invalid set element: " + Expr->getAsString();
  DefInit *OpInit = dynamic_cast<DefInit*>(DagExpr->getOperator());
  if (!OpInit)
    throw "Bad set expression: " + Expr->getAsString();
  Operator *Op = Operators.lookup(OpInit->getDef()->getName());
  if (!Op)
    throw "Unknown set operator: " + Expr->getAsString();
  Op->apply(*this, DagExpr, Elts);
}

const RecVec *SetTheory::expand(Record *Set) {
  // Check existing entries for Set and return early.
  ExpandMap::iterator I = Expansions.find(Set);
  if (I != Expansions.end())
    return &I->second;

  // This is the first time we see Set. Find a suitable expander.
  try {
    const std::vector<Record*> &SC = Set->getSuperClasses();
    for (unsigned i = 0, e = SC.size(); i != e; ++i)
      if (Expander *Exp = Expanders.lookup(SC[i]->getName())) {
        // This breaks recursive definitions.
        RecVec &EltVec = Expansions[Set];
        RecSet Elts;
        Exp->expand(*this, Set, Elts);
        EltVec.assign(Elts.begin(), Elts.end());
        return &EltVec;
      }
  } catch (const std::string &Error) {
    throw TGError(Set->getLoc(), Error);
  }

  // Set is not expandable.
  return 0;
}

