1 //===-- MachineCodeForMethod.cpp -------------------------------------------=//
4 // Collect native machine code information for a function.
5 // This allows target-specific information about the generated code
6 // to be stored with each function.
7 //===---------------------------------------------------------------------===//
9 #include "llvm/CodeGen/MachineCodeForMethod.h"
10 #include "llvm/CodeGen/MachineInstr.h" // For debug output
11 #include "llvm/Target/TargetMachine.h"
12 #include "llvm/Target/MachineFrameInfo.h"
13 #include "llvm/Target/MachineCacheInfo.h"
14 #include "llvm/Function.h"
15 #include "llvm/BasicBlock.h"
16 #include "llvm/iOther.h"
20 const int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits<int>::max();
22 static AnnotationID MCFM_AID(
23 AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
25 // The next two methods are used to construct and to retrieve
26 // the MachineCodeForFunction object for the given function.
27 // construct() -- Allocates and initializes for a given function and target
28 // get() -- Returns a handle to the object.
29 // This should not be called before "construct()"
30 // for a given Function.
33 MachineCodeForMethod::construct(const Function *M, const TargetMachine &Tar)
35 assert(M->getAnnotation(MCFM_AID) == 0 &&
36 "Object already exists for this function!");
37 MachineCodeForMethod* mcInfo = new MachineCodeForMethod(M, Tar);
38 M->addAnnotation(mcInfo);
43 MachineCodeForMethod::destruct(const Function *M)
45 bool Deleted = M->deleteAnnotation(MCFM_AID);
46 assert(Deleted && "Machine code did not exist for function!");
50 MachineCodeForMethod::get(const Function *F)
52 MachineCodeForMethod *mc = (MachineCodeForMethod*)F->getAnnotation(MCFM_AID);
53 assert(mc && "Call construct() method first to allocate the object");
58 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
59 unsigned &maxOptionalNumArgs)
61 const MachineFrameInfo& frameInfo = target.getFrameInfo();
63 unsigned int maxSize = 0;
65 for (Function::const_iterator MI = F->begin(), ME = F->end(); MI != ME; ++MI)
67 const BasicBlock *BB = *MI;
68 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I)
69 if (CallInst *callInst = dyn_cast<CallInst>(*I))
71 unsigned int numOperands = callInst->getNumOperands() - 1;
72 int numExtra =(int)numOperands-frameInfo.getNumFixedOutgoingArgs();
76 unsigned int sizeForThisCall;
77 if (frameInfo.argsOnStackHaveFixedSize())
79 int argSize = frameInfo.getSizeOfEachArgOnStack();
80 sizeForThisCall = numExtra * (unsigned) argSize;
84 assert(0 && "UNTESTED CODE: Size per stack argument is not "
85 "fixed on this architecture: use actual arg sizes to "
86 "compute MaxOptionalArgsSize");
88 for (unsigned i=0; i < numOperands; ++i)
89 sizeForThisCall += target.findOptimalStorageSize(callInst->
90 getOperand(i)->getType());
93 if (maxSize < sizeForThisCall)
94 maxSize = sizeForThisCall;
96 if (((int) maxOptionalNumArgs) < numExtra)
97 maxOptionalNumArgs = (unsigned) numExtra;
104 // Align data larger than one L1 cache line on L1 cache line boundaries.
105 // Align all smaller data on the next higher 2^x boundary (4, 8, ...).
107 // THIS FUNCTION HAS BEEN COPIED FROM EMITASSEMBLY.CPP AND
108 // SHOULD BE USED DIRECTLY THERE
111 SizeToAlignment(unsigned int size, const TargetMachine& target)
113 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
114 if (size > (unsigned) cacheLineSize / 2)
115 return cacheLineSize;
117 for (unsigned sz=1; /*no condition*/; sz *= 2)
125 MachineCodeForMethod::MachineCodeForMethod(const Function *F,
126 const TargetMachine& target)
127 : Annotation(MCFM_AID),
128 method(F), staticStackSize(0),
129 automaticVarsSize(0), regSpillsSize(0),
130 maxOptionalArgsSize(0), maxOptionalNumArgs(0),
131 currentTmpValuesSize(0), maxTmpValuesSize(0), compiledAsLeaf(false),
132 spillsAreaFrozen(false), automaticVarsAreaFrozen(false)
134 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method,
136 staticStackSize = maxOptionalArgsSize
137 + target.getFrameInfo().getMinStackFrameSize();
141 MachineCodeForMethod::computeOffsetforLocalVar(const TargetMachine& target,
143 unsigned int& getPaddedSize,
144 unsigned int sizeToUse = 0)
147 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
152 sizeToUse = target.findOptimalStorageSize(val->getType());
153 // align = target.DataLayout.getTypeAlignment(val->getType());
156 align = SizeToAlignment(sizeToUse, target);
158 int offset = getAutomaticVarsSize();
162 if (unsigned int mod = offset % align)
164 offset += align - mod;
165 getPaddedSize = sizeToUse + align - mod;
168 getPaddedSize = sizeToUse;
170 offset = growUp? firstOffset + offset
171 : firstOffset - offset;
177 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
179 unsigned int sizeToUse = 0)
181 assert(! automaticVarsAreaFrozen &&
182 "Size of auto vars area has been used to compute an offset so "
183 "no more automatic vars should be allocated!");
185 // Check if we've allocated a stack slot for this value already
187 int offset = getOffset(val);
188 if (offset == INVALID_FRAME_OFFSET)
190 unsigned int getPaddedSize;
191 offset = this->computeOffsetforLocalVar(target, val, getPaddedSize,
193 offsets[val] = offset;
194 incrementAutomaticVarsSize(getPaddedSize);
200 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
203 assert(! spillsAreaFrozen &&
204 "Size of reg spills area has been used to compute an offset so "
205 "no more register spill slots should be allocated!");
207 unsigned int size = target.findOptimalStorageSize(type);
208 unsigned char align = target.DataLayout.getTypeAlignment(type);
211 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
213 int offset = getRegSpillsSize();
217 if (unsigned int mod = offset % align)
219 offset += align - mod;
223 offset = growUp? firstOffset + offset
224 : firstOffset - offset;
226 incrementRegSpillsSize(size);
232 MachineCodeForMethod::pushTempValue(const TargetMachine& target,
235 // Compute a power-of-2 alignment according to the possible sizes,
236 // but not greater than the alignment of the largest type we support
237 // (currently a double word -- see class TargetData).
238 unsigned char align = 1;
239 for (; align < size && align < target.DataLayout.getDoubleAlignment();
244 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
246 int offset = currentTmpValuesSize;
250 if (unsigned int mod = offset % align)
252 offset += align - mod;
256 offset = growUp ? firstTmpOffset + offset : firstTmpOffset - offset;
258 incrementTmpAreaSize(size);
263 MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
269 MachineCodeForMethod::getOffset(const Value* val) const
271 std::hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
272 return (pair == offsets.end())? INVALID_FRAME_OFFSET : pair->second;
276 MachineCodeForMethod::dump() const
278 std::cerr << "\n" << method->getReturnType()
279 << " \"" << method->getName() << "\"\n";
281 for (Function::const_iterator BI = method->begin(); BI != method->end(); ++BI)
283 BasicBlock* bb = *BI;
284 std::cerr << "\n" << bb->getName() << " (" << bb << ")" << ":\n";
286 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
287 for (unsigned i=0; i < mvec.size(); i++)
288 std::cerr << "\t" << *mvec[i];
290 std::cerr << "\nEnd function \"" << method->getName() << "\"\n\n";