MachineFunction.cpp revision 0b12b5f50ec77a8bd01b92d287c52d748619bb4b
1235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com//===-- MachineCodeForMethod.cpp -------------------------------------------=//
2235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com//
373ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com// Purpose:
473ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com//   Collect native machine code information for a function.
5235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com//   This allows target-specific information about the generated code
6235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com//   to be stored with each function.
7235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com//===---------------------------------------------------------------------===//
8235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
9235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/CodeGen/MachineCodeForMethod.h"
10235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/CodeGen/MachineInstr.h"  // For debug output
11235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/Target/TargetMachine.h"
12235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/Target/MachineFrameInfo.h"
13235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/Target/MachineCacheInfo.h"
14235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/Function.h"
15235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/BasicBlock.h"
16235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com#include "llvm/iOther.h"
1773ca6243b31e225e9fd5b75a96cbc82d62557de6caryclark@google.com#include <limits.h>
189f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com#include <iostream>
19235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
20235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.comconst int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits<int>::max();
21235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
22235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.comstatic AnnotationID MCFM_AID(
23235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com                 AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
249f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
259f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// The next two methods are used to construct and to retrieve
269f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// the MachineCodeForFunction object for the given function.
279f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// construct() -- Allocates and initializes for a given function and target
289f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// get()       -- Returns a handle to the object.
299f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com//                This should not be called before "construct()"
30235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com//                for a given Function.
31235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com//
32235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.comMachineCodeForMethod&
339f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.comMachineCodeForMethod::construct(const Function *M, const TargetMachine &Tar)
349f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com{
359f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  assert(M->getAnnotation(MCFM_AID) == 0 &&
369f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com         "Object already exists for this function!");
379f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  MachineCodeForMethod* mcInfo = new MachineCodeForMethod(M, Tar);
389f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  M->addAnnotation(mcInfo);
399f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  return *mcInfo;
409f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com}
419f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
42aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.comvoid
439f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.comMachineCodeForMethod::destruct(const Function *M)
449f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com{
459f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  bool Deleted = M->deleteAnnotation(MCFM_AID);
46aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com  assert(Deleted && "Machine code did not exist for function!");
47235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com}
489f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
49aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.comMachineCodeForMethod&
50aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.comMachineCodeForMethod::get(const Function *F)
51235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com{
52235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  MachineCodeForMethod *mc = (MachineCodeForMethod*)F->getAnnotation(MCFM_AID);
53235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  assert(mc && "Call construct() method first to allocate the object");
54235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  return *mc;
55235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com}
56235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
57235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.comstatic unsigned
589f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.comComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
599f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                           unsigned &maxOptionalNumArgs)
609f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com{
619f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  const MachineFrameInfo& frameInfo = target.getFrameInfo();
629f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
639f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  unsigned maxSize = 0;
649f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
659f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
669f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
679f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com      if (const CallInst *callInst = dyn_cast<CallInst>(&*I))
689f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com        {
699f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          unsigned numOperands = callInst->getNumOperands() - 1;
709f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs();
719f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          if (numExtra <= 0)
729f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com            continue;
739f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
749f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          unsigned int sizeForThisCall;
759f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          if (frameInfo.argsOnStackHaveFixedSize())
769f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com            {
779f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com              int argSize = frameInfo.getSizeOfEachArgOnStack();
789f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com              sizeForThisCall = numExtra * (unsigned) argSize;
799f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com            }
809f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          else
819f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com            {
82aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com              assert(0 && "UNTESTED CODE: Size per stack argument is not "
839f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                     "fixed on this architecture: use actual arg sizes to "
849f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                     "compute MaxOptionalArgsSize");
859f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com              sizeForThisCall = 0;
86aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com              for (unsigned i = 0; i < numOperands; ++i)
879f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                sizeForThisCall += target.findOptimalStorageSize(callInst->
889f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                                              getOperand(i)->getType());
899f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com            }
909f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
919f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          if (maxSize < sizeForThisCall)
92aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com            maxSize = sizeForThisCall;
93aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com
949f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com          if ((int)maxOptionalNumArgs < numExtra)
959f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com            maxOptionalNumArgs = (unsigned) numExtra;
969f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com        }
979f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
989f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  return maxSize;
99aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com}
1009f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
101aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com// Align data larger than one L1 cache line on L1 cache line boundaries.
1029f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// Align all smaller data on the next higher 2^x boundary (4, 8, ...).
1039f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com//
1049f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// THIS FUNCTION HAS BEEN COPIED FROM EMITASSEMBLY.CPP AND
1059f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com// SHOULD BE USED DIRECTLY THERE
1069f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com//
107235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.cominline unsigned int
108235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.comSizeToAlignment(unsigned int size, const TargetMachine& target)
109235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com{
110235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
111235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  if (size > (unsigned) cacheLineSize / 2)
1129f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    return cacheLineSize;
113235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  else
114235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com    for (unsigned sz=1; /*no condition*/; sz *= 2)
115235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com      if (sz >= size)
116235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com        return sz;
117235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com}
118235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
1199f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
1209f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
1219f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com/*ctor*/
1229f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.comMachineCodeForMethod::MachineCodeForMethod(const Function *F,
1239f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                                           const TargetMachine& target)
1249f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  : Annotation(MCFM_AID),
1259f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    method(F), staticStackSize(0),
1269f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    automaticVarsSize(0), regSpillsSize(0),
1279f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    maxOptionalArgsSize(0), maxOptionalNumArgs(0),
1289f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    currentTmpValuesSize(0), maxTmpValuesSize(0), compiledAsLeaf(false),
1299f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    spillsAreaFrozen(false), automaticVarsAreaFrozen(false)
1309f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com{
1319f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method,
1329f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                                                   maxOptionalNumArgs);
1339f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  staticStackSize = maxOptionalArgsSize
1345e0500fb5f17fe14db42fc3e0aad08e6b41ccc5fcaryclark@google.com                    + target.getFrameInfo().getMinStackFrameSize();
1359f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com}
1369f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
137aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.comint
138aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.comMachineCodeForMethod::computeOffsetforLocalVar(const TargetMachine& target,
1399f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                                               const Value* val,
1409f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                                               unsigned int& getPaddedSize,
1419f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                                               unsigned int  sizeToUse = 0)
1429f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com{
1439f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  bool growUp;
1449f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
145aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com                                                                    growUp);
146aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com  unsigned char align;
1479f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  if (sizeToUse == 0)
1489f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    {
1499f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com      sizeToUse = target.findOptimalStorageSize(val->getType());
1509f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com      // align = target.DataLayout.getTypeAlignment(val->getType());
1519f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    }
1529f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
153aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com  align = SizeToAlignment(sizeToUse, target);
1549f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
155aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com  int offset = getAutomaticVarsSize();
1569f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  if (! growUp)
1579f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    offset += sizeToUse;
1589f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
1599f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  if (unsigned int mod = offset % align)
1609f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    {
1619f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com      offset        += align - mod;
162aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com      getPaddedSize  = sizeToUse + align - mod;
1639f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    }
1649f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  else
165aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com    getPaddedSize  = sizeToUse;
1669f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
1679f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  offset = growUp? firstOffset + offset
1689f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    : firstOffset - offset;
1699f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com
1709f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  return offset;
171235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com}
172235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
173235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.comint
174235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.comMachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
175235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com                                       const Value* val,
176235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com                                       unsigned int sizeToUse = 0)
177235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com{
178235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  assert(! automaticVarsAreaFrozen &&
1799f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com         "Size of auto vars area has been used to compute an offset so "
180235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com         "no more automatic vars should be allocated!");
181235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
182235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  // Check if we've allocated a stack slot for this value already
183235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  //
184235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  int offset = getOffset(val);
185235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com  if (offset == INVALID_FRAME_OFFSET)
186235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com    {
187235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com      unsigned int getPaddedSize;
1889f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com      offset = this->computeOffsetforLocalVar(target, val, getPaddedSize,
1899f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com                                              sizeToUse);
1909f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com      offsets[val] = offset;
1919f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com      incrementAutomaticVarsSize(getPaddedSize);
1929f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com    }
1939f60291c5375457f8adf228dbe6e8ff1186b13e1caryclark@google.com  return offset;
194235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com}
195235f56a92f6eb6accbb243e11b3c45e3798f38f2caryclark@google.com
196int
197MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
198                                           const Type* type)
199{
200  assert(! spillsAreaFrozen &&
201         "Size of reg spills area has been used to compute an offset so "
202         "no more register spill slots should be allocated!");
203
204  unsigned int size  = target.findOptimalStorageSize(type);
205  unsigned char align = target.DataLayout.getTypeAlignment(type);
206
207  bool growUp;
208  int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
209
210  int offset = getRegSpillsSize();
211  if (! growUp)
212    offset += size;
213
214  if (unsigned int mod = offset % align)
215    {
216      offset    += align - mod;
217      size += align - mod;
218    }
219
220  offset = growUp? firstOffset + offset
221                 : firstOffset - offset;
222
223  incrementRegSpillsSize(size);
224
225  return offset;
226}
227
228int
229MachineCodeForMethod::pushTempValue(const TargetMachine& target,
230                                    unsigned int size)
231{
232  // Compute a power-of-2 alignment according to the possible sizes,
233  // but not greater than the alignment of the largest type we support
234  // (currently a double word -- see class TargetData).
235  unsigned char align = 1;
236  for (; align < size && align < target.DataLayout.getDoubleAlignment();
237         align = 2*align)
238    ;
239
240  bool growUp;
241  int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
242
243  int offset = currentTmpValuesSize;
244  if (! growUp)
245    offset += size;
246
247  if (unsigned int mod = offset % align)
248    {
249      offset += align - mod;
250      size   += align - mod;
251    }
252
253  offset = growUp ? firstTmpOffset + offset : firstTmpOffset - offset;
254
255  incrementTmpAreaSize(size);
256  return offset;
257}
258
259void
260MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
261{
262  resetTmpAreaSize();
263}
264
265int
266MachineCodeForMethod::getOffset(const Value* val) const
267{
268  std::hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
269  return (pair == offsets.end())? INVALID_FRAME_OFFSET : pair->second;
270}
271
272void
273MachineCodeForMethod::dump() const
274{
275  std::cerr << "\n" << method->getReturnType()
276            << " \"" << method->getName() << "\"\n";
277
278  for (Function::const_iterator BB = method->begin(); BB != method->end(); ++BB)
279    {
280      std::cerr << "\n" << BB->getName() << " (" << *BB << ")" << ":\n";
281
282      MachineCodeForBasicBlock& mvec = BB->getMachineInstrVec();
283      for (unsigned i=0; i < mvec.size(); i++)
284	std::cerr << "\t" << *mvec[i];
285    }
286  std::cerr << "\nEnd function \"" << method->getName() << "\"\n\n";
287}
288