//===-- SparcV9FunctionInfo.cpp -------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This implements the SparcV9 specific MachineFunctionInfo class.
//
//===----------------------------------------------------------------------===//

#include "MachineFunctionInfo.h"
#include "llvm/Instructions.h"
#include "llvm/Function.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetFrameInfo.h"
using namespace llvm;

static unsigned
ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
                           unsigned &maxOptionalNumArgs)
{
  unsigned maxSize = 0;

  for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
      if (const CallInst *callInst = dyn_cast<CallInst>(I))
        {
          unsigned numOperands = callInst->getNumOperands() - 1;
          int numExtra = numOperands-6;
          if (numExtra <= 0)
            continue;

          unsigned sizeForThisCall = numExtra * 8;

          if (maxSize < sizeForThisCall)
            maxSize = sizeForThisCall;

          if ((int)maxOptionalNumArgs < numExtra)
            maxOptionalNumArgs = (unsigned) numExtra;
        }

  return maxSize;
}

// Align data larger than one L1 cache line on L1 cache line boundaries.
// Align all smaller data on the next higher 2^x boundary (4, 8, ...),
// but not higher than the alignment of the largest type we support
// (currently a double word). -- see class TargetData).
//
// This function is similar to the corresponding function in EmitAssembly.cpp
// but they are unrelated.  This one does not align at more than a
// double-word boundary whereas that one might.
//
inline unsigned
SizeToAlignment(unsigned size, const TargetMachine& target)
{
  const unsigned short cacheLineSize = 16;
  if (size > (unsigned) cacheLineSize / 2)
    return cacheLineSize;
  else
    for (unsigned sz=1; /*no condition*/; sz *= 2)
      if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
        return sz;
}


void SparcV9FunctionInfo::CalculateArgSize() {
  maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
                                                   MF.getFunction(),
                                                   maxOptionalNumArgs);
  staticStackSize = maxOptionalArgsSize + 176;
}

int
SparcV9FunctionInfo::computeOffsetforLocalVar(const Value* val,
                                              unsigned &getPaddedSize,
                                              unsigned  sizeToUse)
{
  if (sizeToUse == 0) {
    // All integer types smaller than ints promote to 4 byte integers.
    if (val->getType()->isIntegral() && val->getType()->getPrimitiveSize() < 4)
      sizeToUse = 4;
    else
      sizeToUse = MF.getTarget().getTargetData().getTypeSize(val->getType());
  }
  unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());

  bool growUp;
  int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF,
                                                                             growUp);
  int offset = growUp? firstOffset + getAutomaticVarsSize()
                     : firstOffset - (getAutomaticVarsSize() + sizeToUse);

  int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
  getPaddedSize = sizeToUse + abs(aligned - offset);

  return aligned;
}


int SparcV9FunctionInfo::allocateLocalVar(const Value* val,
                                          unsigned sizeToUse) {
  assert(! automaticVarsAreaFrozen &&
         "Size of auto vars area has been used to compute an offset so "
         "no more automatic vars should be allocated!");

  // Check if we've allocated a stack slot for this value already
  //
  hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
  if (pair != offsets.end())
    return pair->second;

  unsigned getPaddedSize;
  unsigned offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
  offsets[val] = offset;
  incrementAutomaticVarsSize(getPaddedSize);
  return offset;
}

int
SparcV9FunctionInfo::allocateSpilledValue(const Type* type)
{
  assert(! spillsAreaFrozen &&
         "Size of reg spills area has been used to compute an offset so "
         "no more register spill slots should be allocated!");

  unsigned size  = MF.getTarget().getTargetData().getTypeSize(type);
  unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);

  bool growUp;
  int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp);

  int offset = growUp? firstOffset + getRegSpillsSize()
                     : firstOffset - (getRegSpillsSize() + size);

  int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
  size += abs(aligned - offset); // include alignment padding in size

  incrementRegSpillsSize(size);  // update size of reg. spills area

  return aligned;
}

int
SparcV9FunctionInfo::pushTempValue(unsigned size)
{
  unsigned align = SizeToAlignment(size, MF.getTarget());

  bool growUp;
  int firstOffset = MF.getTarget().getFrameInfo()->getTmpAreaOffset(MF, growUp);

  int offset = growUp? firstOffset + currentTmpValuesSize
                     : firstOffset - (currentTmpValuesSize + size);

  int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp,
                                                              align);
  size += abs(aligned - offset); // include alignment padding in size

  incrementTmpAreaSize(size);    // update "current" size of tmp area

  return aligned;
}

void SparcV9FunctionInfo::popAllTempValues() {
  resetTmpAreaSize();            // clear tmp area to reuse
}
