1 //===-- MachineCodeForMethod.cpp --------------------------------------------=//
4 // Collect native machine code information for a method.
5 // This allows target-specific information about the generated code
6 // to be stored with each method.
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/Method.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::MachineCodeForMethod"));
25 // The next two methods are used to construct and to retrieve
26 // the MachineCodeForMethod object for the given method.
27 // construct() -- Allocates and initializes for a given method and target
28 // get() -- Returns a handle to the object.
29 // This should not be called before "construct()"
30 // for a given Method.
33 MachineCodeForMethod::construct(const Method *M, const TargetMachine &Tar)
35 assert(M->getAnnotation(MCFM_AID) == 0 &&
36 "Object already exists for this method!");
37 MachineCodeForMethod* mcInfo = new MachineCodeForMethod(M, Tar);
38 M->addAnnotation(mcInfo);
43 MachineCodeForMethod::destruct(const Method *M)
45 bool Deleted = M->deleteAnnotation(MCFM_AID);
46 assert(Deleted && "Machine code did not exist for method!");
50 MachineCodeForMethod::get(const Method* method)
52 MachineCodeForMethod* mc = (MachineCodeForMethod*)
53 method->getAnnotation(MCFM_AID);
54 assert(mc && "Call construct() method first to allocate the object");
59 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
61 const MachineFrameInfo& frameInfo = target.getFrameInfo();
63 unsigned int maxSize = 0;
65 for (Method::const_iterator MI=method->begin(), ME=method->end();
68 const BasicBlock *BB = *MI;
69 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
70 if (CallInst *callInst = dyn_cast<CallInst>(*I))
72 unsigned int numOperands = callInst->getNumOperands() - 1;
73 int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
77 unsigned int sizeForThisCall;
78 if (frameInfo.argsOnStackHaveFixedSize())
80 int argSize = frameInfo.getSizeOfEachArgOnStack();
81 sizeForThisCall = numExtra * (unsigned) argSize;
85 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
87 for (unsigned i=0; i < numOperands; ++i)
88 sizeForThisCall += target.findOptimalStorageSize(callInst->
89 getOperand(i)->getType());
92 if (maxSize < sizeForThisCall)
93 maxSize = sizeForThisCall;
100 // Align data larger than one L1 cache line on L1 cache line boundaries.
101 // Align all smaller data on the next higher 2^x boundary (4, 8, ...).
103 // THIS FUNCTION HAS BEEN COPIED FROM EMITASSEMBLY.CPP AND
104 // SHOULD BE USED DIRECTLY THERE
107 SizeToAlignment(unsigned int size, const TargetMachine& target)
109 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
110 if (size > (unsigned) cacheLineSize / 2)
111 return cacheLineSize;
113 for (unsigned sz=1; /*no condition*/; sz *= 2)
121 MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
122 const TargetMachine& target)
123 : Annotation(MCFM_AID),
124 method(_M), compiledAsLeaf(false), staticStackSize(0),
125 automaticVarsSize(0), regSpillsSize(0),
126 currentOptionalArgsSize(0), maxOptionalArgsSize(0),
127 currentTmpValuesSize(0)
129 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
130 staticStackSize = maxOptionalArgsSize
131 + target.getFrameInfo().getMinStackFrameSize();
135 MachineCodeForMethod::computeOffsetforLocalVar(const TargetMachine& target,
140 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
145 size = target.findOptimalStorageSize(val->getType());
146 // align = target.DataLayout.getTypeAlignment(val->getType());
149 align = SizeToAlignment(size, target);
151 int offset = getAutomaticVarsSize();
155 if (unsigned int mod = offset % align)
157 offset += align - mod;
161 offset = growUp? firstOffset + offset
162 : firstOffset - offset;
168 MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
172 // Check if we've allocated a stack slot for this value already
174 int offset = getOffset(val);
175 if (offset == INVALID_FRAME_OFFSET)
177 offset = this->computeOffsetforLocalVar(target, val, size);
178 offsets[val] = offset;
179 incrementAutomaticVarsSize(size);
185 MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
188 unsigned int size = target.findOptimalStorageSize(type);
189 unsigned char align = target.DataLayout.getTypeAlignment(type);
192 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
194 int offset = getRegSpillsSize();
198 if (unsigned int mod = offset % align)
200 offset += align - mod;
204 offset = growUp? firstOffset + offset
205 : firstOffset - offset;
207 incrementRegSpillsSize(size);
213 MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
216 const MachineFrameInfo& frameInfo = target.getFrameInfo();
219 if (frameInfo.argsOnStackHaveFixedSize())
220 size = frameInfo.getSizeOfEachArgOnStack();
223 size = target.findOptimalStorageSize(type);
224 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
226 unsigned char align = target.DataLayout.getTypeAlignment(type);
229 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
231 int offset = getCurrentOptionalArgsSize();
235 if (unsigned int mod = offset % align)
237 offset += align - mod;
241 offset = growUp? firstOffset + offset
242 : firstOffset - offset;
244 incrementCurrentOptionalArgsSize(size);
250 MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
252 currentOptionalArgsSize = 0;
256 MachineCodeForMethod::pushTempValue(const TargetMachine& target,
259 // Compute a power-of-2 alignment according to the possible sizes,
260 // but not greater than the alignment of the largest type we support
261 // (currently a double word -- see class TargetData).
262 unsigned char align = 1;
263 for (; align < size && align < target.DataLayout.getDoubleAlignment();
268 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
270 int offset = currentTmpValuesSize;
274 if (unsigned int mod = offset % align)
276 offset += align - mod;
280 offset = growUp ? firstTmpOffset + offset : firstTmpOffset - offset;
282 currentTmpValuesSize += size;
287 MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
289 currentTmpValuesSize = 0;
293 MachineCodeForMethod::getOffset(const Value* val) const
295 std::hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
296 return (pair == offsets.end())? INVALID_FRAME_OFFSET : pair->second;
300 MachineCodeForMethod::dump() const
302 std::cerr << "\n" << method->getReturnType()
303 << " \"" << method->getName() << "\"\n";
305 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
307 BasicBlock* bb = *BI;
308 std::cerr << "\n" << bb->getName() << " (" << bb << ")" << ":\n";
310 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
311 for (unsigned i=0; i < mvec.size(); i++)
312 std::cerr << "\t" << *mvec[i];
314 std::cerr << "\nEnd method \"" << method->getName() << "\"\n\n";