//===-------------------------- TargetRecip.cpp ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class is used to customize machine-specific reciprocal estimate code
// generation in a target-independent way.
// If a target does not support operations in this specification, then code
// generation will default to using supported operations.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetRecip.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;

// These are the names of the individual reciprocal operations. These are
// the key strings for queries and command-line inputs.
// In addition, the command-line interface recognizes the global parameters
// "all", "none", and "default".
static const char *const RecipOps[] = {
  "divd",
  "divf",
  "vec-divd",
  "vec-divf",
  "sqrtd",
  "sqrtf",
  "vec-sqrtd",
  "vec-sqrtf",
};

// The uninitialized state is needed for the enabled settings and refinement
// steps because custom settings may arrive via the command-line before target
// defaults are set.
TargetRecip::TargetRecip() {
  unsigned NumStrings = llvm::array_lengthof(RecipOps);
  for (unsigned i = 0; i < NumStrings; ++i)
    RecipMap.insert(std::make_pair(RecipOps[i], RecipParams()));
}

static bool parseRefinementStep(StringRef In, size_t &Position,
                                uint8_t &Value) {
  const char RefStepToken = ':';
  Position = In.find(RefStepToken);
  if (Position == StringRef::npos)
    return false;

  StringRef RefStepString = In.substr(Position + 1);
  // Allow exactly one numeric character for the additional refinement
  // step parameter.
  if (RefStepString.size() == 1) {
    char RefStepChar = RefStepString[0];
    if (RefStepChar >= '0' && RefStepChar <= '9') {
      Value = RefStepChar - '0';
      return true;
    }
  }
  report_fatal_error("Invalid refinement step for -recip.");
}

bool TargetRecip::parseGlobalParams(const std::string &Arg) {
  StringRef ArgSub = Arg;

  // Look for an optional setting of the number of refinement steps needed
  // for this type of reciprocal operation.
  size_t RefPos;
  uint8_t RefSteps;
  StringRef RefStepString;
  if (parseRefinementStep(ArgSub, RefPos, RefSteps)) {
    // Split the string for further processing.
    RefStepString = ArgSub.substr(RefPos + 1);
    ArgSub = ArgSub.substr(0, RefPos);
  }
  bool Enable;
  bool UseDefaults;
  if (ArgSub == "all") {
    UseDefaults = false;
    Enable = true;
  } else if (ArgSub == "none") {
    UseDefaults = false;
    Enable = false;
  } else if (ArgSub == "default") {
    UseDefaults = true;
  } else {
    // Any other string is invalid or an individual setting.
    return false;
  }

  // All enable values will be initialized to target defaults if 'default' was
  // specified.
  if (!UseDefaults)
    for (auto &KV : RecipMap)
      KV.second.Enabled = Enable;

  // Custom refinement count was specified with all, none, or default.
  if (!RefStepString.empty())
    for (auto &KV : RecipMap)
      KV.second.RefinementSteps = RefSteps;
  
  return true;
}

void TargetRecip::parseIndividualParams(const std::vector<std::string> &Args) {
  static const char DisabledPrefix = '!';
  unsigned NumArgs = Args.size();

  for (unsigned i = 0; i != NumArgs; ++i) {
    StringRef Val = Args[i];
    
    bool IsDisabled = Val[0] == DisabledPrefix;
    // Ignore the disablement token for string matching.
    if (IsDisabled)
      Val = Val.substr(1);
    
    size_t RefPos;
    uint8_t RefSteps;
    StringRef RefStepString;
    if (parseRefinementStep(Val, RefPos, RefSteps)) {
      // Split the string for further processing.
      RefStepString = Val.substr(RefPos + 1);
      Val = Val.substr(0, RefPos);
    }

    RecipIter Iter = RecipMap.find(Val);
    if (Iter == RecipMap.end()) {
      // Try again specifying float suffix.
      Iter = RecipMap.find(Val.str() + 'f');
      if (Iter == RecipMap.end()) {
        Iter = RecipMap.find(Val.str() + 'd');
        assert(Iter == RecipMap.end() && "Float entry missing from map");
        report_fatal_error("Invalid option for -recip.");
      }
      
      // The option was specified without a float or double suffix.
      if (RecipMap[Val.str() + 'd'].Enabled != Uninitialized) {
        // Make sure that the double entry was not already specified.
        // The float entry will be checked below.
        report_fatal_error("Duplicate option for -recip.");
      }
    }
    
    if (Iter->second.Enabled != Uninitialized)
      report_fatal_error("Duplicate option for -recip.");
    
    // Mark the matched option as found. Do not allow duplicate specifiers.
    Iter->second.Enabled = !IsDisabled;
    if (!RefStepString.empty())
      Iter->second.RefinementSteps = RefSteps;
    
    // If the precision was not specified, the double entry is also initialized.
    if (Val.back() != 'f' && Val.back() != 'd') {
      RecipParams &Params = RecipMap[Val.str() + 'd'];
      Params.Enabled = !IsDisabled;
      if (!RefStepString.empty())
        Params.RefinementSteps = RefSteps;
    }
  }
}

TargetRecip::TargetRecip(const std::vector<std::string> &Args) :
  TargetRecip() {
  unsigned NumArgs = Args.size();

  // Check if "all", "default", or "none" was specified.
  if (NumArgs == 1 && parseGlobalParams(Args[0]))
    return;
 
  parseIndividualParams(Args);
}

bool TargetRecip::isEnabled(StringRef Key) const {
  ConstRecipIter Iter = RecipMap.find(Key);
  assert(Iter != RecipMap.end() && "Unknown name for reciprocal map");
  assert(Iter->second.Enabled != Uninitialized &&
         "Enablement setting was not initialized");
  return Iter->second.Enabled;
}

unsigned TargetRecip::getRefinementSteps(StringRef Key) const {
  ConstRecipIter Iter = RecipMap.find(Key);
  assert(Iter != RecipMap.end() && "Unknown name for reciprocal map");
  assert(Iter->second.RefinementSteps != Uninitialized &&
         "Refinement step setting was not initialized");
  return Iter->second.RefinementSteps;
}

/// Custom settings (previously initialized values) override target defaults.
void TargetRecip::setDefaults(StringRef Key, bool Enable,
                              unsigned RefSteps) {
  if (Key == "all") {
    for (auto &KV : RecipMap) {
      RecipParams &RP = KV.second;
      if (RP.Enabled == Uninitialized)
        RP.Enabled = Enable;
      if (RP.RefinementSteps == Uninitialized)
        RP.RefinementSteps = RefSteps;
    }
  } else {
    RecipParams &RP = RecipMap[Key];
    if (RP.Enabled == Uninitialized)
      RP.Enabled = Enable;
    if (RP.RefinementSteps == Uninitialized)
      RP.RefinementSteps = RefSteps;
  }
}

bool TargetRecip::operator==(const TargetRecip &Other) const {
  for (const auto &KV : RecipMap) {
    StringRef Op = KV.first;
    const RecipParams &RP = KV.second;
    const RecipParams &OtherRP = Other.RecipMap.find(Op)->second;
    if (RP.RefinementSteps != OtherRP.RefinementSteps)
      return false;
    if (RP.Enabled != OtherRP.Enabled)
      return false;
  }
  return true;
}
