LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MachineFunctionInfo.cpp

Go to the documentation of this file.
00001 //===-- SparcV9FunctionInfo.cpp -------------------------------------------===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 // 
00010 // This implements the SparcV9 specific MachineFunctionInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "MachineFunctionInfo.h"
00015 #include "llvm/Instructions.h"
00016 #include "llvm/Function.h"
00017 #include "llvm/Type.h"
00018 #include "llvm/CodeGen/MachineFunction.h"
00019 #include "llvm/Target/TargetMachine.h"
00020 #include "llvm/Target/TargetFrameInfo.h"
00021 using namespace llvm;
00022 
00023 static unsigned
00024 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
00025                            unsigned &maxOptionalNumArgs)
00026 {
00027   unsigned maxSize = 0;
00028   
00029   for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
00030     for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
00031       if (const CallInst *callInst = dyn_cast<CallInst>(I))
00032         {
00033           unsigned numOperands = callInst->getNumOperands() - 1;
00034           int numExtra = numOperands-6;
00035           if (numExtra <= 0)
00036             continue;
00037           
00038           unsigned sizeForThisCall = numExtra * 8;
00039           
00040           if (maxSize < sizeForThisCall)
00041             maxSize = sizeForThisCall;
00042           
00043           if ((int)maxOptionalNumArgs < numExtra)
00044             maxOptionalNumArgs = (unsigned) numExtra;
00045         }
00046   
00047   return maxSize;
00048 }
00049 
00050 // Align data larger than one L1 cache line on L1 cache line boundaries.
00051 // Align all smaller data on the next higher 2^x boundary (4, 8, ...),
00052 // but not higher than the alignment of the largest type we support
00053 // (currently a double word). -- see class TargetData).
00054 //
00055 // This function is similar to the corresponding function in EmitAssembly.cpp
00056 // but they are unrelated.  This one does not align at more than a
00057 // double-word boundary whereas that one might.
00058 // 
00059 inline unsigned
00060 SizeToAlignment(unsigned size, const TargetMachine& target)
00061 {
00062   const unsigned short cacheLineSize = 16;
00063   if (size > (unsigned) cacheLineSize / 2)
00064     return cacheLineSize;
00065   else
00066     for (unsigned sz=1; /*no condition*/; sz *= 2)
00067       if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
00068         return sz;
00069 }
00070 
00071 
00072 void SparcV9FunctionInfo::CalculateArgSize() {
00073   maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
00074                MF.getFunction(),
00075                                                    maxOptionalNumArgs);
00076   staticStackSize = maxOptionalArgsSize + 176;
00077 }
00078 
00079 int
00080 SparcV9FunctionInfo::computeOffsetforLocalVar(const Value* val,
00081                 unsigned &getPaddedSize,
00082                 unsigned  sizeToUse)
00083 {
00084   if (sizeToUse == 0) {
00085     // All integer types smaller than ints promote to 4 byte integers.
00086     if (val->getType()->isIntegral() && val->getType()->getPrimitiveSize() < 4)
00087       sizeToUse = 4;
00088     else
00089       sizeToUse = MF.getTarget().getTargetData().getTypeSize(val->getType());
00090   }
00091   unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());
00092 
00093   bool growUp;
00094   int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF,
00095                        growUp);
00096   int offset = growUp? firstOffset + getAutomaticVarsSize()
00097                      : firstOffset - (getAutomaticVarsSize() + sizeToUse);
00098 
00099   int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
00100   getPaddedSize = sizeToUse + abs(aligned - offset);
00101 
00102   return aligned;
00103 }
00104 
00105 
00106 int SparcV9FunctionInfo::allocateLocalVar(const Value* val,
00107                                           unsigned sizeToUse) {
00108   assert(! automaticVarsAreaFrozen &&
00109          "Size of auto vars area has been used to compute an offset so "
00110          "no more automatic vars should be allocated!");
00111   
00112   // Check if we've allocated a stack slot for this value already
00113   // 
00114   hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
00115   if (pair != offsets.end())
00116     return pair->second;
00117 
00118   unsigned getPaddedSize;
00119   unsigned offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
00120   offsets[val] = offset;
00121   incrementAutomaticVarsSize(getPaddedSize);
00122   return offset;
00123 }
00124 
00125 int
00126 SparcV9FunctionInfo::allocateSpilledValue(const Type* type)
00127 {
00128   assert(! spillsAreaFrozen &&
00129          "Size of reg spills area has been used to compute an offset so "
00130          "no more register spill slots should be allocated!");
00131   
00132   unsigned size  = MF.getTarget().getTargetData().getTypeSize(type);
00133   unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
00134   
00135   bool growUp;
00136   int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp);
00137   
00138   int offset = growUp? firstOffset + getRegSpillsSize()
00139                      : firstOffset - (getRegSpillsSize() + size);
00140 
00141   int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
00142   size += abs(aligned - offset); // include alignment padding in size
00143   
00144   incrementRegSpillsSize(size);  // update size of reg. spills area
00145 
00146   return aligned;
00147 }
00148 
00149 int
00150 SparcV9FunctionInfo::pushTempValue(unsigned size)
00151 {
00152   unsigned align = SizeToAlignment(size, MF.getTarget());
00153 
00154   bool growUp;
00155   int firstOffset = MF.getTarget().getFrameInfo()->getTmpAreaOffset(MF, growUp);
00156 
00157   int offset = growUp? firstOffset + currentTmpValuesSize
00158                      : firstOffset - (currentTmpValuesSize + size);
00159 
00160   int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp,
00161                     align);
00162   size += abs(aligned - offset); // include alignment padding in size
00163 
00164   incrementTmpAreaSize(size);    // update "current" size of tmp area
00165 
00166   return aligned;
00167 }
00168 
00169 void SparcV9FunctionInfo::popAllTempValues() {
00170   resetTmpAreaSize();            // clear tmp area to reuse
00171 }