Newer
Older
Vikram S. Adve
committed
// $Id$
//***************************************************************************
// File:
// MachineInstr.cpp
//
// Purpose:
//
//
// Strategy:
//
// History:
// 7/2/01 - Vikram Adve - Created
//**************************************************************************/
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Target/MachineFrameInfo.h"
Vikram S. Adve
committed
#include "llvm/Instruction.h"
AnnotationID MachineCodeForMethod::AID(
AnnotationManager::getID("MachineCodeForMethodAnnotation"));
Vikram S. Adve
committed
Vikram S. Adve
committed
//************************ Class Implementations **************************/
// Constructor for instructions with fixed #operands (nearly all)
Vikram S. Adve
committed
MachineInstr::MachineInstr(MachineOpCode _opCode,
OpCodeMask _opCodeMask)
: opCode(_opCode),
opCodeMask(_opCodeMask),
operands(TargetInstrDescriptors[_opCode].numOperands)
{
assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
}
// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode _opCode,
unsigned numOperands,
OpCodeMask _opCodeMask)
: opCode(_opCode),
opCodeMask(_opCodeMask),
operands(numOperands)
Vikram S. Adve
committed
{
}
void
MachineInstr::SetMachineOperand(unsigned int i,
MachineOperand::MachineOperandType operandType,
Value* _val, bool isdef=false)
Vikram S. Adve
committed
{
assert(i < operands.size());
Vikram S. Adve
committed
operands[i].Initialize(operandType, _val);
operands[i].isDef = isdef ||
Vikram S. Adve
committed
}
void
MachineInstr::SetMachineOperand(unsigned int i,
MachineOperand::MachineOperandType operandType,
int64_t intValue, bool isdef=false)
Vikram S. Adve
committed
{
assert(i < operands.size());
Vikram S. Adve
committed
operands[i].InitializeConst(operandType, intValue);
operands[i].isDef = isdef ||
Vikram S. Adve
committed
}
void
MachineInstr::SetMachineOperand(unsigned int i,
Vikram S. Adve
committed
{
assert(i < operands.size());
Vikram S. Adve
committed
operands[i].InitializeReg(regNum);
operands[i].isDef = isdef ||
Vikram S. Adve
committed
}
void
MachineInstr::dump(unsigned int indent) const
Vikram S. Adve
committed
{
for (unsigned i=0; i < indent; i++)
cout << " ";
cout << *this;
}
ostream&
operator<< (ostream& os, const MachineInstr& minstr)
{
os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adve
committed
for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
os << "\t" << minstr.getOperand(i);
#undef DEBUG_VAL_OP_ITERATOR
#ifdef DEBUG_VAL_OP_ITERATOR
os << endl << "\tValue operands are: ";
for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
{
const Value* val = *vo;
os << val << (vo.isDef()? "(def), " : ", ");
}
#endif
#if 1
// code for printing implict references
unsigned NumOfImpRefs = minstr.getNumImplicitRefs();
if( NumOfImpRefs > 0 ) {
os << "\tImplicit:";
for(unsigned z=0; z < NumOfImpRefs; z++) {
os << minstr.getImplicitRef(z);
cout << "\t";
}
}
#endif
Vikram S. Adve
committed
os << endl;
Vikram S. Adve
committed
return os;
}
static inline ostream&
OutputOperand(ostream &os, const MachineOperand &mop)
{
switch (mop.getOperandType())
{
case MachineOperand::MO_CCRegister:
case MachineOperand::MO_VirtualRegister:
return os << "(val " << mop.getVRegValue() << ")";
case MachineOperand::MO_MachineRegister:
return os << "(" << mop.getMachineRegNum() << ")";
default:
assert(0 && "Unknown operand type");
return os;
}
Vikram S. Adve
committed
ostream&
operator<<(ostream &os, const MachineOperand &mop)
{
switch(mop.opType)
{
case MachineOperand::MO_VirtualRegister:
case MachineOperand::MO_MachineRegister:
os << "%reg";
return OutputOperand(os, mop);
case MachineOperand::MO_CCRegister:
os << "%ccreg";
return OutputOperand(os, mop);
case MachineOperand::MO_SignExtendedImmed:
return os << mop.immedVal;
case MachineOperand::MO_UnextendedImmed:
return os << mop.immedVal;
case MachineOperand::MO_PCRelativeDisp:
{
const Value* opVal = mop.getVRegValue();
bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
return os << "%disp("
<< (isLabel? "label " : "addr-of-val ")
<< opVal << ")";
}
default:
assert(0 && "Unrecognized operand type");
break;
}
Vikram S. Adve
committed
return os;
}
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
static unsigned int
ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
{
const MachineFrameInfo& frameInfo = target.getFrameInfo();
unsigned int maxSize = 0;
for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end();
I != E; ++I)
if ((*I)->getOpcode() == Instruction::Call)
{
CallInst* callInst = cast<CallInst>(*I);
unsigned int numOperands = callInst->getNumOperands() - 1;
unsigned int numExtra = numOperands
- frameInfo.getNumFixedOutgoingArgs();
unsigned int sizeForThisCall;
if (frameInfo.argsOnStackHaveFixedSize())
{
int argSize = frameInfo.getSizeOfEachArgOnStack();
sizeForThisCall = numExtra * (unsigned) argSize;
}
else
{
assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
sizeForThisCall = 0;
for (unsigned i=0; i < numOperands; ++i)
sizeForThisCall += target.findOptimalStorageSize(callInst->
getOperand(i)->getType());
}
if (maxSize < sizeForThisCall)
maxSize = sizeForThisCall;
}
return maxSize;
}
Vikram S. Adve
committed
/*ctor*/
MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
const TargetMachine& target)
: Annotation(AID),
method(_M), compiledAsLeaf(false), staticStackSize(0),
automaticVarsSize(0), regSpillsSize(0),
currentOptionalArgsSize(0), maxOptionalArgsSize(0),
currentTmpValuesSize(0)
maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
staticStackSize = maxOptionalArgsSize +
target.getFrameInfo().getMinStackFrameSize();
int
MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
const Value* val)
{
// Check if we've allocated a stack slot for this value already
//
int offset = getOffset(val);
if (offset == INVALID_FRAME_OFFSET)
{
bool growUp;
int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
growUp);
offset = growUp? firstOffset + getAutomaticVarsSize()
: firstOffset - getAutomaticVarsSize();
offsets[val] = offset;
unsigned int size = target.findOptimalStorageSize(val->getType());
incrementAutomaticVarsSize(size);
}
return offset;
}
int
MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
const Type* type)
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
bool growUp;
int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
int offset = growUp? firstOffset + getRegSpillsSize()
: firstOffset - getRegSpillsSize();
unsigned int size = target.findOptimalStorageSize(type);
incrementRegSpillsSize(size);
return offset;
}
int
MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
const Type* type)
{
const MachineFrameInfo& frameInfo = target.getFrameInfo();
bool growUp;
int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
int offset = growUp? firstOffset + getCurrentOptionalArgsSize()
: firstOffset - getCurrentOptionalArgsSize();
int size = MAXINT;
if (frameInfo.argsOnStackHaveFixedSize())
size = frameInfo.getSizeOfEachArgOnStack();
else
{
assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
size = target.findOptimalStorageSize(type);
}
incrementCurrentOptionalArgsSize(size);
return offset;
void
MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
{
currentOptionalArgsSize = 0;
}
MachineCodeForMethod::pushTempValue(const TargetMachine& target,
unsigned int size)
{
bool growUp;
int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
int offset = growUp? firstTmpOffset + currentTmpValuesSize
: firstTmpOffset - currentTmpValuesSize;
currentTmpValuesSize += size;
return offset;
}
void
MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
// void
// MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local,
// int offset,
// unsigned int size)
// {
// offsetsFromSP[local] = offset;
// incrementAutomaticVarsSize(size);
// }
//
MachineCodeForMethod::getOffset(const Value* val) const
hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second;
// int
// MachineCodeForMethod::getOffsetFromSP(const Value* local) const
// {
// hash_map<const Value*, int>::const_iterator pair = offsetsFromSP.find(local);
// return (pair == offsetsFromSP.end())? INVALID_FRAME_OFFSET : (*pair).second;
// }
void
MachineCodeForMethod::dump() const
{
cout << "\n" << method->getReturnType()
<< " \"" << method->getName() << "\"" << endl;
for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
{
BasicBlock* bb = *BI;
cout << "\n"
<< (bb->hasName()? bb->getName() : "Label")
<< " (" << bb << ")" << ":"
<< endl;
MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
for (unsigned i=0; i < mvec.size(); i++)
Vikram S. Adve
committed
cout << "\t" << *mvec[i];
}
cout << endl << "End method \"" << method->getName() << "\""
<< endl << endl;
}