LLVM API Documentation
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 }