aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-03-18 03:15:35 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-03-18 03:15:35 +0000
commit7482532129d8f181f4d826a7362d500310db32b0 (patch)
treecdfdfd8da3809a8b40eb7b62d9b7901f0f11608e
parentf1c15ee4d15c3632343fccb723cce6f1d35bb5ba (diff)
Add support for code generation for array references.
Also, use distinct names for the three types of SetMachineOperand to avoid painful overloading problems and errors. Bug fix in converting-int-to-float. Other minor stuff. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1896 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp1088
1 files changed, 607 insertions, 481 deletions
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index 059935981f..e3764ece0c 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -12,6 +12,7 @@
#include "SparcInternals.h"
#include "SparcInstrSelectionSupport.h"
+#include "SparcRegClassInfo.h"
#include "llvm/CodeGen/InstrSelectionSupport.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/InstrForest.h"
@@ -32,10 +33,10 @@ using std::vector;
//************************* Forward Declarations ***************************/
-static void SetMemOperands_Internal (MachineInstr* minstr,
+static void SetMemOperands_Internal (vector<MachineInstr*>& mvec,
+ vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
Value* ptrVal,
- Value* arrayOffsetVal,
const std::vector<Value*>& idxVec,
const TargetMachine& target);
@@ -259,12 +260,12 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
break;
case ToDoubleTy:
- // Use FXTOD for all integer-to-double conversions. This has to be
- // consistent with the code in CreateCodeToCopyIntToFloat() since
- // that will be used to load the integer into an FP register.
- //
- if (opType == Type::SByteTy || opType == Type::ShortTy ||
- opType == Type::IntTy || opType == Type::LongTy)
+ // This is usually used in conjunction with CreateCodeToCopyIntToFloat().
+ // Both functions should treat the integer as a 32-bit value for types
+ // of 4 bytes or less, and as a 64-bit value otherwise.
+ if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
+ opCode = FITOD;
+ else if (opType == Type::LongTy)
opCode = FXTOD;
else if (opType == Type::FloatTy)
opCode = FSTOD;
@@ -356,10 +357,10 @@ CreateMovFloatInstruction(const InstructionNode* instrNode,
{
MachineInstr* minstr = new MachineInstr((resultType == Type::FloatTy)
? FMOVS : FMOVD);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ minstr->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ instrNode->leftChild()->getValue());
+ minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ instrNode->getValue());
return minstr;
}
@@ -490,46 +491,38 @@ ChooseMulInstructionByType(const Type* resultType)
}
-static inline MachineOpCode
-ChooseMulInstruction(const InstructionNode* instrNode,
- bool checkCasts)
-{
- if (checkCasts && BothFloatToDouble(instrNode))
- return FSMULD;
-
- // else use the regular multiply instructions
- return ChooseMulInstructionByType(instrNode->getInstruction()->getType());
-}
-
static inline MachineInstr*
-CreateIntNegInstruction(TargetMachine& target,
+CreateIntNegInstruction(const TargetMachine& target,
Value* vreg)
{
MachineInstr* minstr = new MachineInstr(SUB);
- minstr->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, vreg);
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, vreg);
+ minstr->SetMachineOperandReg(0, target.getRegInfo().getZeroRegNum());
+ minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, vreg);
+ minstr->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, vreg);
return minstr;
}
-static inline MachineInstr*
-CreateMulConstInstruction(TargetMachine &target,
- const InstructionNode* instrNode,
- MachineInstr*& getMinstr2)
+// Does not create any instructions if we cannot exploit constant to
+// create a cheaper instruction
+static inline void
+CreateMulConstInstruction(const TargetMachine &target,
+ Value* lval, Value* rval, Value* destVal,
+ vector<MachineInstr*>& mvec)
{
- MachineInstr* minstr = NULL; // return NULL if we cannot exploit constant
- getMinstr2 = NULL; // to create a cheaper instruction
-
- Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
- assert(isa<Constant>(constOp));
+ MachineInstr* minstr1 = NULL;
+ MachineInstr* minstr2 = NULL;
+
+ Value* constOp = rval;
+ if (! isa<Constant>(constOp))
+ return;
// Cases worth optimizing are:
// (1) Multiply by 0 or 1 for any type: replace with copy (ADD or FMOV)
// (2) Multiply by 2^x for integer types: replace with Shift
//
- const Type* resultType = instrNode->getInstruction()->getType();
+ const Type* resultType = destVal->getType();
if (resultType->isIntegral() || resultType->isPointerType())
{
@@ -547,30 +540,29 @@ CreateMulConstInstruction(TargetMachine &target,
if (C == 0 || C == 1)
{
- minstr = new MachineInstr(ADD);
+ minstr1 = new MachineInstr(ADD);
if (C == 0)
- minstr->SetMachineOperand(0,
+ minstr1->SetMachineOperandReg(0,
target.getRegInfo().getZeroRegNum());
else
- minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
+ minstr1->SetMachineOperandVal(0,MachineOperand::MO_VirtualRegister,
+ lval);
+ minstr1->SetMachineOperandReg(1,target.getRegInfo().getZeroRegNum());
}
else if (IsPowerOf2(C, pow))
{
- minstr = new MachineInstr((resultType == Type::LongTy)
+ minstr1 = new MachineInstr((resultType == Type::LongTy)
? SLLX : SLL);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
- pow);
+ minstr1->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ lval);
+ minstr1->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
+ pow);
}
- if (minstr && needNeg)
+ if (minstr1 && needNeg)
{ // insert <reg = SUB 0, reg> after the instr to flip the sign
- getMinstr2 = CreateIntNegInstruction(target,
- instrNode->getValue());
+ minstr2 = CreateIntNegInstruction(target, destVal);
}
}
}
@@ -588,19 +580,47 @@ CreateMulConstInstruction(TargetMachine &target,
? (resultType == Type::FloatTy? FNEGS : FNEGD)
: (resultType == Type::FloatTy? FMOVS : FMOVD);
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0,
- MachineOperand::MO_VirtualRegister,
- instrNode->leftChild()->getValue());
+ minstr1 = new MachineInstr(opCode);
+ minstr1->SetMachineOperandVal(0,
+ MachineOperand::MO_VirtualRegister,
+ lval);
}
}
}
- if (minstr != NULL)
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ if (minstr1 != NULL)
+ minstr1->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ destVal);
- return minstr;
+ if (minstr1)
+ mvec.push_back(minstr1);
+ if (minstr2)
+ mvec.push_back(minstr2);
+}
+
+
+// Return NULL if we cannot exploit constant to create a cheaper instruction
+static inline void
+CreateMulInstruction(const TargetMachine &target,
+ Value* lval, Value* rval, Value* destVal,
+ vector<MachineInstr*>& mvec,
+ MachineOpCode forceMulOp = INVALID_MACHINE_OPCODE)
+{
+ unsigned int L = mvec.size();
+ CreateMulConstInstruction(target, lval, rval, destVal, mvec);
+ if (mvec.size() == L)
+ { // no instructions were added so create MUL reg, reg, reg.
+ // Use FSMULD if both operands are actually floats cast to doubles.
+ // Otherwise, use the default opcode for the appropriate type.
+ MachineOpCode mulOp = ((forceMulOp != INVALID_MACHINE_OPCODE)
+ ? forceMulOp
+ : ChooseMulInstructionByType(destVal->getType()));
+ MachineInstr* M = new MachineInstr(mulOp);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, lval);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, rval);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, destVal);
+ mvec.push_back(M);
+ }
}
@@ -630,16 +650,18 @@ ChooseDivInstruction(TargetMachine &target,
}
-static inline MachineInstr*
+// Return NULL if we cannot exploit constant to create a cheaper instruction
+static inline void
CreateDivConstInstruction(TargetMachine &target,
const InstructionNode* instrNode,
- MachineInstr*& getMinstr2)
+ vector<MachineInstr*>& mvec)
{
- MachineInstr* minstr = NULL;
- getMinstr2 = NULL;
+ MachineInstr* minstr1 = NULL;
+ MachineInstr* minstr2 = NULL;
Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
- assert(isa<Constant>(constOp));
+ if (! isa<Constant>(constOp))
+ return;
// Cases worth optimizing are:
// (1) Divide by 1 for any type: replace with copy (ADD or FMOV)
@@ -663,26 +685,26 @@ CreateDivConstInstruction(TargetMachine &target,
if (C == 1)
{
- minstr = new MachineInstr(ADD);
- minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
+ minstr1 = new MachineInstr(ADD);
+ minstr1->SetMachineOperandVal(0,MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
+ minstr1->SetMachineOperandReg(1,target.getRegInfo().getZeroRegNum());
}
else if (IsPowerOf2(C, pow))
{
MachineOpCode opCode= ((resultType->isSigned())
? (resultType==Type::LongTy)? SRAX : SRA
: (resultType==Type::LongTy)? SRLX : SRL);
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ minstr1 = new MachineInstr(opCode);
+ minstr1->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
- minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
+ minstr1->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
pow);
}
- if (minstr && needNeg)
+ if (minstr1 && needNeg)
{ // insert <reg = SUB 0, reg> after the instr to flip the sign
- getMinstr2 = CreateIntNegInstruction(target,
+ minstr2 = CreateIntNegInstruction(target,
instrNode->getValue());
}
}
@@ -701,21 +723,116 @@ CreateDivConstInstruction(TargetMachine &target,
? (resultType == Type::FloatTy? FNEGS : FNEGD)
: (resultType == Type::FloatTy? FMOVS : FMOVD);
- minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ minstr1 = new MachineInstr(opCode);
+ minstr1->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
instrNode->leftChild()->getValue());
}
}
}
- if (minstr != NULL)
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instrNode->getValue());
+ if (minstr1 != NULL)
+ minstr1->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ instrNode->getValue());
- return minstr;
+ if (minstr1)
+ mvec.push_back(minstr1);
+ if (minstr2)
+ mvec.push_back(minstr2);
+}
+
+
+static void
+CreateCodeForVariableSizeAlloca(const TargetMachine& target,
+ Instruction* result,
+ unsigned int tsize,
+ Value* numElementsVal,
+ vector<MachineInstr*>& getMvec)
+{
+ MachineInstr* M;
+
+ // Create a Value to hold the (constant) element size
+ Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
+
+ // Get the constant offset from SP for dynamically allocated storage
+ // and create a temporary Value to hold it.
+ assert(result && result->getParent() && "Result value is not part of a method?");
+ Method* method = result->getParent()->getParent();
+ MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
+ bool growUp;
+ ConstantSInt* dynamicAreaOffset =
+ ConstantSInt::get(Type::IntTy,
+ target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
+ assert(! growUp && "Has SPARC v9 stack frame convention changed?");
+
+ // Create a temporary value to hold the result of MUL
+ TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
+ MachineCodeForInstruction::get(result).addTemp(tmpProd);
+
+ // Instruction 1: mul numElements, typeSize -> tmpProd
+ M = new MachineInstr(MULX);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, numElementsVal);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tsizeVal);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, tmpProd);
+ getMvec.push_back(M);
+
+ // Instruction 2: sub %sp, tmpProd -> %sp
+ M = new MachineInstr(SUB);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpProd);
+ M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+ getMvec.push_back(M);
+
+ // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
+ M = new MachineInstr(ADD);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, dynamicAreaOffset);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
+ getMvec.push_back(M);
+}
+
+
+static void
+CreateCodeForFixedSizeAlloca(const TargetMachine& target,
+ Instruction* result,
+ unsigned int tsize,
+ unsigned int numElements,
+ vector<MachineInstr*>& getMvec)
+{
+ assert(result && result->getParent() && "Result value is not part of a method?");
+ Method* method = result->getParent()->getParent();
+ MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
+
+ // Check if the offset would small enough to use as an immediate in load/stores
+ // (check LDX because all load/stores have the same-size immediate field).
+ // If not, put the variable in the dynamically sized area of the frame.
+ int offsetFromFP = mcInfo.computeOffsetforLocalVar(target, result,
+ tsize * numElements);
+ if (! target.getInstrInfo().constantFitsInImmedField(LDX, offsetFromFP))
+ {
+ CreateCodeForVariableSizeAlloca(target, result, tsize,
+ ConstantSInt::get(Type::IntTy,numElements),
+ getMvec);
+ return;
+ }
+
+ // else offset fits in immediate field so go ahead and allocate it.
+ offsetFromFP = mcInfo.allocateLocalVar(target, result, tsize * numElements);
+
+ // Create a temporary Value to hold the constant offset.
+ // This is needed because it may not fit in the immediate field.
+ ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP);
+
+ // Instruction 1: add %fp, offsetFromFP -> result
+ MachineInstr* M = new MachineInstr(ADD);
+ M->SetMachineOperandReg(0, target.getRegInfo().getFramePointer());
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, offsetVal);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
+
+ getMvec.push_back(M);
}
+
//------------------------------------------------------------------------
// Function SetOperandsForMemInstr
//
@@ -733,7 +850,8 @@ CreateDivConstInstruction(TargetMachine &target,
//------------------------------------------------------------------------
static void
-SetOperandsForMemInstr(MachineInstr* minstr,
+SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
+ vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
const TargetMachine& target)
{
@@ -744,8 +862,7 @@ SetOperandsForMemInstr(MachineInstr* minstr,
// and then call the common function SetMemOperands_Internal().
//
vector<Value*> idxVec;
- Value* ptrVal;
- Value* arrayOffsetVal = NULL;
+ Value* ptrVal = memInst->getPointerOperand();
// Test if a GetElemPtr instruction is being folded into this mem instrn.
// If so, it will be in the left child for Load and GetElemPtr,
@@ -755,49 +872,39 @@ SetOperandsForMemInstr(MachineInstr* minstr,
? vmInstrNode->rightChild()
: vmInstrNode->leftChild());
- if (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
- ptrChild->getOpLabel() == GetElemPtrIdx)
+ // We can only fold a chain of GetElemPtr instructions for structure references
+ //
+ if (isa<StructType>(cast<PointerType>(ptrVal->getType())->getElementType())
+ && (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
+ ptrChild->getOpLabel() == GetElemPtrIdx))
{
// There is a GetElemPtr instruction and there may be a chain of
// more than one. Use the pointer value of the last one in the chain.
// Fold the index vectors from the entire chain and from the mem
// instruction into one single index vector.
- // Finally, we never fold for an array instruction so make that NULL.
-
- ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, idxVec);
- idxVec.insert(idxVec.end(), memInst->idx_begin(), memInst->idx_end());
- assert(!((PointerType*)ptrVal->getType())->getElementType()->isArrayType()
- && "GetElemPtr cannot be folded into array refs in selection");
- }
- else
- {
- // There is no GetElemPtr instruction.
- // Use the pointer value and the index vector from the Mem instruction.
- // If it is an array reference, check that it has been lowered to
- // at most a single offset, then get the array offset value.
//
- ptrVal = memInst->getPointerOperand();
+ ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, idxVec);
- const Type* opType = cast<PointerType>(ptrVal->getType())->getElementType();
- if (opType->isArrayType())
- {
- assert((memInst->getNumOperands()
- == (unsigned) 1 + memInst->getFirstIndexOperandNumber())
- && "Array refs must be lowered before Instruction Selection");
- arrayOffsetVal = * memInst->idx_begin();
- }
+ assert (! cast<PointerType>(ptrVal->getType())->getElementType()->isArrayType()
+ && "GetElemPtr cannot be folded into array refs in selection");
}
- SetMemOperands_Internal(minstr, vmInstrNode, ptrVal, arrayOffsetVal,
- idxVec, target);
+ // Append the index vector of this instruction (may be none) to the indexes
+ // folded in previous getElementPtr's (may be none)
+ idxVec.insert(idxVec.end(), memInst->idx_begin(), memInst->idx_end());
+
+ SetMemOperands_Internal(mvec, mvecI, vmInstrNode, ptrVal, idxVec, target);
}
+// Generate the correct operands (and additional instructions if needed)
+// for the given pointer and given index vector.
+//
static void
-SetMemOperands_Internal(MachineInstr* minstr,
+SetMemOperands_Internal(vector<MachineInstr*>& mvec,
+ vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
Value* ptrVal,
- Value* arrayOffsetVal,
const vector<Value*>& idxVec,
const TargetMachine& target)
{
@@ -808,51 +915,70 @@ SetMemOperands_Internal(MachineInstr* minstr,
Value* valueForRegOffset = NULL;
MachineOperand::MachineOperandType offsetOpType =MachineOperand::MO_VirtualRegister;
- // Check if there is an index vector and if so, if it translates to
- // a small enough constant to fit in the immediate-offset field.
+ // Check if there is an index vector and if so, compute the
+ // right offset for structures and for arrays
//
if (idxVec.size() > 0)
{
- bool isConstantOffset = false;
unsigned offset = 0;
- const PointerType* ptrType = (PointerType*) ptrVal->getType();
+ const PointerType* ptrType = cast<PointerType>(ptrVal->getType());
if (ptrType->getElementType()->isStructType())
{
- // the offset is always constant for structs
- isConstantOffset = true;
-
- // Compute the offset value using the index vector
- offset = target.DataLayout.getIndexedOffset(ptrType, idxVec);
+ // Compute the offset value using the index vector,
+ // and create a virtual register for it.
+ unsigned offset = target.DataLayout.getIndexedOffset(ptrType,idxVec);
+ valueForRegOffset = ConstantSInt::get(Type::IntTy, offset);
}
else
{
- // It must be an array ref. Check if the offset is a constant,
- // and that the indexing has been lowered to a single offset.
- //
- assert(isa<SequentialType>(ptrType->getElementType()));
- assert(arrayOffsetVal != NULL
- && "Expect to be given Value* for array offsets");
+ // It must be an array ref. Check that the indexing has been
+ // lowered to a single offset.
+ assert((memInst->getNumOperands()
+ == (unsigned) 1 + memInst->getFirstIndexOperandNumber())
+ && "Array refs must be lowered before Instruction Selection");
- if (Constant *CPV = dyn_cast<Constant>(arrayOffsetVal))
- {
- isConstantOffset = true; // always constant for structs
- assert(arrayOffsetVal->getType()->isIntegral());
- offset = (CPV->getType()->isSigned()
- ? cast<ConstantSInt>(CPV)->getValue()
- : (int64_t) cast<ConstantUInt>(CPV)->getValue());
- }
- else
+ Value* arrayOffsetVal = * memInst->idx_begin();
+
+ // Generate a MUL instruction to compute address from index
+ // The call to getTypeSize() will fail if size is not constant
+ vector<MachineInstr*> mulVec;
+ Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
+ MachineCodeForInstruction::get(memInst).addTemp(addr);
+ unsigned int eltSize =
+ target.DataLayout.getTypeSize(ptrType->getElementType());
+ assert(eltSize > 0 && "Invalid or non-constant array element size");
+ ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize);
+
+ CreateMulInstruction(target,
+ arrayOffsetVal, /* lval, not likely constant */
+ eltVal, /* rval, likely constant */
+ addr, /* result*/
+ mulVec, INVALID_MACHINE_OPCODE);
+ assert(mulVec.size() > 0 && "No multiply instruction created?");
+ for (vector<MachineInstr*>::const_iterator I = mulVec.begin();
+ I != mulVec.end(); ++I)
{
- valueForRegOffset = arrayOffsetVal;
+ mvecI = mvec.insert(mvecI, *I); // get ptr to inserted value
+ ++mvecI; // get ptr to mem. instr.
}
- }
-
- if (isConstantOffset)
- {
- // create a virtual register for the constant
- valueForRegOffset = ConstantSInt::get(Type::IntTy, offset);
+
+ valueForRegOffset = addr;
+
+ // Check if the offset is a constant,
+ // if (Constant *CPV = dyn_cast<Constant>(arrayOffsetVal))
+ // {
+ // isConstantOffset = true; // always constant for structs
+ // assert(arrayOffsetVal->getType()->isIntegral());
+ // offset = (CPV->getType()->isSigned()
+ // ? cast<ConstantSInt>(CPV)->getValue()
+ // : (int64_t) cast<ConstantUInt>(CPV)->getValue());
+ // }
+ // else
+ // {
+ // valueForRegOffset = arrayOffsetVal;
+ // }
}
}
else
@@ -864,7 +990,8 @@ SetMemOperands_Internal(MachineInstr* minstr,
// Operand 0 is value for STORE, ptr for LOAD or GET_ELEMENT_PTR
// It is the left child in the instruction tree in all cases.
Value* leftVal = vmInstrNode->leftChild()->getValue();
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, leftVal);
+ (*mvecI)->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ leftVal);
// Operand 1 is ptr for STORE, offset for LOAD or GET_ELEMENT_PTR
// Operand 2 is offset for STORE, result reg for LOAD or GET_ELEMENT_PTR
@@ -873,16 +1000,19 @@ SetMemOperands_Internal(MachineInstr* minstr,
if (offsetOpType == MachineOperand::MO_VirtualRegister)
{
assert(valueForRegOffset != NULL);
- minstr->SetMachineOperand(offsetOpNum, offsetOpType, valueForRegOffset);
+ (*mvecI)->SetMachineOperandVal(offsetOpNum, offsetOpType,
+ valueForRegOffset);
}
else
- minstr->SetMachineOperand(offsetOpNum, offsetOpType, smallConstOffset);
+ (*mvecI)->SetMachineOperandConst(offsetOpNum, offsetOpType,
+ smallConstOffset);
if (memInst->getOpcode() == Instruction::Store)
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, ptrVal);
+ (*mvecI)->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ ptrVal);
else
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- vmInstrNode->getValue());
+ (*mvecI)->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ vmInstrNode->getValue());
}
@@ -890,6 +1020,9 @@ SetMemOperands_Internal(MachineInstr* minstr,
// Substitute operand `operandNum' of the instruction in node `treeNode'
// in place of the use(s) of that instruction in node `parent'.
// Check both explicit and implicit operands!
+// Also make sure to skip over a parent who:
+// (1) is a list node in the Burg tree, or
+// (2) itself had its results forwarded to its parent
//
static void
ForwardOperand(InstructionNode* treeNode,
@@ -911,31 +1044,50 @@ ForwardOperand(InstructionNode* treeNode,
Instruction* userInstr = parentInstrNode->getInstruction();
MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(userInstr);
- for (unsigned i=0, N=mvec.size(); i < N; i++)
+
+ // The parent's mvec would be empty if it was itself forwarded.
+ // Recursively call ForwardOperand in that case...
+ //
+ if (mvec.size() == 0)
{
- MachineInstr* minstr = mvec[i];
-
- for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
+ assert(parent->parent() != NULL &&
+ "Parent could not have been forwarded, yet has no instructions?");
+ ForwardOperand(treeNode, parent->parent(), operandNum);
+ }
+ else
+ {
+ bool fwdSuccessful = false;
+ for (unsigned i=0, N=mvec.size(); i < N; i++)
{
- const MachineOperand& mop = minstr->getOperand(i);
- if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
- mop.getVRegValue() == unusedOp)
+ MachineInstr* minstr = mvec[i];
+ for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
{
- minstr->SetMachineOperand(i, MachineOperand::MO_VirtualRegister,
- fwdOp);
+ const MachineOperand& mop = minstr->getOperand(i);
+ if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
+ mop.getVRegValue() == unusedOp)
+ {
+ minstr->SetMachineOperandVal(i,
+ MachineOperand::MO_VirtualRegister, fwdOp);
+ fwdSuccessful = true;
+ }
}
+
+ for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); i<numOps; ++i)
+ if (minstr->getImplicitRef(i) == unusedOp)
+ {
+ minstr->setImplicitRef(i, fwdOp,
+ minstr->implicitRefIsDefined(i));
+ fwdSuccessful = true;
+ }
}
-
- for (unsigned i=0, numOps=minstr->getNumImplicitRefs(); i < numOps; ++i)
- if (minstr->getImplicitRef(i) == unusedOp)
- minstr->setImplicitRef(i, fwdOp, minstr->implicitRefIsDefined(i));
+ assert(fwdSuccessful && "Value to be forwarded is never used!");
}
}
-
void UltraSparcInstrInfo::
CreateCopyInstructionsByType(const TargetMachine& target,
+ Method* method,
Value* src,
Instruction* dest,
vector<MachineInstr*>& minstrVec) const
@@ -973,23 +1125,23 @@ CreateCopyInstructionsByType(const TargetMachine& target,
{ // `src' is constant and cannot fit in immed field for the ADD
// Insert instructions to "load" the constant into a register
vector<TmpInstruction*> tempVec;
- target.getInstrInfo().CreateCodeToLoadConst(src,dest,minstrVec,tempVec);
+ target.getInstrInfo().CreateCodeToLoadConst(method, src, dest,minstrVec,tempVec);
for (unsigned i=0; i < tempVec.size(); i++)
MachineCodeForInstruction::get(dest).addTemp(tempVec[i]);
}
else
- { // Create the appropriate add instruction.
+ { // Create an add-with-0 instruction of the appropriate type.
// Make `src' the second operand, in case it is a constant
// Use (unsigned long) 0 for a NULL pointer value.
//
- const Type* nullValueType =
+ const Type* zeroValueType =
(resultType->getPrimitiveID() == Type::PointerTyID)? Type::ULongTy
: resultType;
MachineInstr* minstr = new MachineInstr(opCode);
- minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- Constant::getNullConstant(nullValueType));
- minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, src);
- minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
+ minstr->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ Constant::getNullConstant(zeroValueType));
+ minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, src);
+ minstr->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,dest);
minstrVec.push_back(minstr);
}
}
@@ -1012,12 +1164,15 @@ GetInstructionsForProlog(BasicBlock* entryBB,
TargetMachine &target,
MachineInstr** mvec)
{
+ MachineInstr* M;
const MachineFrameInfo& frameInfo = target.getFrameInfo();
+ unsigned int N = 0;
// The second operand is the stack size. If it does not fit in the
- // immediate field, we either have to find an unused register in the
- // caller's window or move some elements to the dynamically allocated
- // area of the stack frame (just above save area and method args).
+ // immediate field, we have to use a free register to hold the size.
+ // We will assume that local register `l0' is unused since the SAVE
+ // instruction must be the first instruction in each procedure.
+ //
Method* method = entryBB->getParent();
MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
unsigned int staticStackSize = mcInfo.getStaticStackSize();
@@ -1029,16 +1184,37 @@ GetInstructionsForProlog(BasicBlock* entryBB,
(unsigned) frameInfo.getStackFrameSizeAlignment()))
staticStackSize += frameInfo.getStackFrameSizeAlignment() - padsz;
- assert(target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize)
- && "Stack size too large for immediate field of SAVE instruction. Need additional work as described in the comment above");
-
- mvec[0] = new MachineInstr(SAVE);
- mvec[0]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
- - (int) staticStackSize);
- mvec[0]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
+ if (target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize))
+ {
+ M = new MachineInstr(SAVE);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
+ - (int) staticStackSize);
+ M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+ mvec[N++] = M;
+ }
+ else
+ {
+ M = new MachineInstr(SETSW);
+ M->SetMachineOperandReg(0, MachineOperand::MO_SignExtendedImmed,
+ - staticStackSize);
+ M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
+ target.getRegInfo().getUnifiedRegNum(
+ target.getRegInfo().getRegClassIDOfType(Type::IntTy),
+ SparcIntRegOrder::l0));
+ mvec[N++] = M;
+
+ M = new MachineInstr(SAVE);
+ M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+ M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
+ target.getRegInfo().getUnifiedRegNum(
+ target.getRegInfo().getRegClassIDOfType(Type::IntTy),
+ SparcIntRegOrder::l0));
+ M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+ mvec[N++] = M;
+ }
- return 1;
+ return N;
}
@@ -1048,10 +1224,10 @@ GetInstructionsForEpilog(BasicBlock* anExitBB,
MachineInstr** mvec)
{
mvec[0] = new MachineInstr(RESTORE);
- mvec[0]->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+ mvec[0]->SetMachineOperandReg(0, target.getRegInfo().getZeroRegNum());
+ mvec[0]->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
(int64_t)0);
- mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
+ mvec[0]->SetMachineOperandReg(2, target.getRegInfo().getZeroRegNum());
return 1;
}
@@ -1105,20 +1281,21 @@ ThisIsAChainRule(int eruleno)
// patterns chosen by the BURG-generated parser.
//------------------------------------------------------------------------
-unsigned
+void
GetInstructionsByRule(InstructionNode* subtreeRoot,
int ruleForNode,
short* nts,
TargetMachine &target,
- MachineInstr** mvec)
+ vector<MachineInstr*>& mvec)
{
- int numInstr = 1; // initialize for common case
bool checkCast = false; // initialize here to use fall-through
int nextRule;
int forwardOperandNum = -1;
-
- for (unsigned i=0; i < MAX_INSTR_PER_VMINSTR; i++)
- mvec[i] = NULL;
+ unsigned int allocaSize = 0;
+ MachineInstr* M, *M2;
+ unsigned int L;
+
+ mvec.clear();
//
// Let's check for chain rules outside the switch so that we don't have
@@ -1133,7 +1310,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
&& "A chain rule should have only one RHS non-terminal!");
nextRule = burm_rule(subtreeRoot->state, nts[0]);
nts = burm_nts[nextRule];
- numInstr = GetInstructionsByRule(subtreeRoot, nextRule, nts,target,mvec);
+ GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec);
}
else
{
@@ -1153,39 +1330,40 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
Instruction* returnReg = new TmpInstruction(returnInstr);
MachineCodeForInstruction::get(returnInstr).addTemp(returnReg);
- mvec[0] = new MachineInstr(JMPLRET);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(JMPLRET);
+ M->SetMachineOperandReg(0, MachineOperand::MO_VirtualRegister,
returnReg);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+ M->SetMachineOperandConst(1,MachineOperand::MO_SignExtendedImmed,
(int64_t)8);
- mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
+ M->SetMachineOperandReg(2, target.getRegInfo().getZeroRegNum());
if (returnInstr->getReturnValue() != NULL)
- mvec[0]->addImplicitRef(returnInstr->getReturnValue());
+ M->addImplicitRef(returnInstr->getReturnValue());
- unsigned n = numInstr++; // delay slot
- mvec[n] = new MachineInstr(NOP);
+ mvec.push_back(M);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
case 3: // stmt: Store(reg,reg)
case 4: // stmt: Store(reg,ptrreg)
- mvec[0] = new MachineInstr(
- ChooseStoreInstruction(
- subtreeRoot->leftChild()->getValue()->getType()));
- SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(
+ ChooseStoreInstruction(
+ subtreeRoot->leftChild()->getValue()->getType())));
+ SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
break;
case 5: // stmt: BrUncond
- mvec[0] = new MachineInstr(BA);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
(Value*)NULL);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
case 206: // stmt: BrCond(setCCconst)
@@ -1209,25 +1387,26 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// That constant is a zero after all...
// Use the left child of setCC as the first argument!
- mvec[0] = new MachineInstr(ChooseBprInstruction(subtreeRoot));
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(ChooseBprInstruction(subtreeRoot));
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
subtreeRoot->leftChild()->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
- brInst->getSuccessor(0));
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+ brInst->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
// false branch
- int n = numInstr++;
- mvec[n] = new MachineInstr(BA);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
brInst->getSuccessor(1));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1244,30 +1423,30 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
//
BranchInst* brInst = cast<BranchInst>(subtreeRoot->getInstruction());
bool isFPBranch;
- mvec[0] = new MachineInstr(ChooseBccInstruction(subtreeRoot,
- isFPBranch));
+ M = new MachineInstr(ChooseBccInstruction(subtreeRoot, isFPBranch));
Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
brInst->getParent()->getParent(),
isFPBranch? Type::FloatTy : Type::IntTy);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister, ccValue);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
- brInst->getSuccessor(0));
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister, ccValue);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+ brInst->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
// false branch
- int n = numInstr++;
- mvec[n] = new MachineInstr(BA);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
- brInst->getSuccessor(1));
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+ brInst->getSuccessor(1));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1278,14 +1457,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
cast<Constant>(subtreeRoot->leftChild()->getValue());
unsigned dest = cast<ConstantBool>(constVal)->getValue()? 0 : 1;
- mvec[0] = new MachineInstr(BA);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(dest));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1293,31 +1473,31 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ // boolreg => boolean is stored in an existing register.
// Just use the branch-on-integer-register instruction!
//
- mvec[0] = new MachineInstr(BRNZ);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(BRNZ);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP); // delay slot
+ mvec.push_back(new MachineInstr(NOP));
// false branch
- int n = numInstr++;
- mvec[n] = new MachineInstr(BA);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- (Value*) NULL);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+ M = new MachineInstr(BA);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ (Value*) NULL);
+ M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
+ mvec.push_back(M);
// delay slot
- mvec[numInstr++] = new MachineInstr(NOP);
+ mvec.push_back(new MachineInstr(NOP));
break;
}
case 9: // stmt: Switch(reg)
assert(0 && "*** SWITCH instruction is not implemented yet.");
- numInstr = 0;
break;
case 10: // reg: VRegList(reg, reg)
@@ -1326,12 +1506,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 21: // bool: Not(bool): Both these are implemented as:
case 321: // reg: BNot(reg) : reg = reg XOR-NOT 0
- mvec[0] = new MachineInstr(XNOR);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- subtreeRoot->getValue());
+ M = new MachineInstr(XNOR);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ subtreeRoot->leftChild()->getValue());
+ M->SetMachineOperandReg(1, target.getRegInfo().getZeroRegNum());
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ subtreeRoot->getValue());
+ mvec.push_back(M);
break;
case 322: // reg: ToBoolTy(bool):
@@ -1340,8 +1521,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
assert(opType->isIntegral() || opType->isPointerType()
|| opType == Type::BoolTy);
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
break;
}
@@ -1354,8 +1534,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
assert(opType->isIntegral() ||
opType->isPointerType() ||
opType == Type::BoolTy && "Cast is illegal for other types");
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
break;
}
@@ -1369,8 +1548,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|| opType->isPointerType()
|| opType == Type::BoolTy)
{
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
}
else
{
@@ -1412,15 +1590,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
MachineOpCode opCode=ChooseConvertToIntInstr(subtreeRoot, opType);
assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
- mvec[0] = new MachineInstr(opCode);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- leftVal);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- destForCast);
-
- assert(numInstr == 1 && "Should be initialized to 1 at the top");
- for (unsigned i=0; i < minstrVec.size(); ++i)
- mvec[numInstr++] = minstrVec[i];
+ M = new MachineInstr(opCode);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ leftVal);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ destForCast);
+ mvec.push_back(M);
+
+ // Append the copy code, if any, after the conversion instr.
+ mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
}
break;
}
@@ -1438,8 +1616,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
if (subtreeRoot->parent() != NULL &&
MachineCodeForInstruction::get(((InstructionNode*)subtreeRoot->parent())->getInstruction())[0]->getOpCode() == FSMULD)
{
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
}
else
{
@@ -1448,8 +1625,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType);
if (opCode == INVALID_OPCODE) // no conversion needed
{
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
}
else
{
@@ -1482,53 +1658,56 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
leftVal, (TmpInstruction*) srcForCast,
minstrVec, tempVec, target);
- for (unsigned i=0; i < minstrVec.size(); ++i)
- mvec[n++] = minstrVec[i];
-
+ mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end());
+
for (unsigned i=0; i < tempVec.size(); ++i)
DestMCFI.addTemp(tempVec[i]);
}
else
srcForCast = leftVal;
- MachineInstr* castI = new MachineInstr(opCode);
- castI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- srcForCast);
- castI->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- dest);
- mvec[n++] = castI;
- numInstr = n;
+ M = new MachineInstr(opCode);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ srcForCast);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ dest);
+ mvec.push_back(M);
}
}
break;
case 19: // reg: ToArrayTy(reg):
case 20: // reg: ToPointerTy(reg):
- numInstr = 0;
- forwardOperandNum = 0;
+ forwardOperandNum = 0; // forward first operand to user
break;
case 233: // reg: Add(reg, Constant)
- mvec[0] = CreateAddConstInstruction(subtreeRoot);
- if (mvec[0] != NULL)
- break;
+ M = CreateAddConstInstruction(subtreeRoot);
+ if (M != NULL)
+ {
+ mvec.push_back(M);
+ break;
+ }
// ELSE FALL THROUGH
-
+
case 33: // reg: Add(reg, reg)
- mvec[0] = new MachineInstr(ChooseAddInstruction(subtreeRoot));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseAddInstruction(subtreeRoot)));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 234: // reg: Sub(reg, Constant)
- mvec[0] = CreateSubConstInstruction(subtreeRoot);
- if (mvec[0] != NULL)
- break;
+ M = CreateSubConstInstruction(subtreeRoot);
+ if (M != NULL)
+ {
+ mvec.push_back(M);
+ break;
+ }
// ELSE FALL THROUGH
-
+
case 34: // reg: Sub(reg, reg)
- mvec[0] = new MachineInstr(ChooseSubInstructionByType(
- subtreeRoot->getInstruction()->getType()));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseSubInstructionByType(
+ subtreeRoot->getInstruction()->getType())));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 135: // reg: Mul(todouble, todouble)
@@ -1536,40 +1715,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// FALL THROUGH
case 35: // reg: Mul(reg, reg)
- mvec[0] =new MachineInstr(ChooseMulInstruction(subtreeRoot,checkCast));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ {
+ MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
+ ? FSMULD
+ : INVALID_MACHINE_OPCODE);
+ CreateMulInstruction(target,
+ subtreeRoot->leftChild()->getValue(),
+ subtreeRoot->rightChild()->getValue(),
+ subtreeRoot->getInstruction(),
+ mvec, forceOp);
break;
-
+ }
case 335: // reg: Mul(todouble, todoubleConst)
checkCast = true;
// FALL THROUGH
case 235: // reg: Mul(reg, Constant)
- mvec[0] = CreateMulConstInstruction(target, subtreeRoot, mvec[1]);
- if (mvec[0] == NULL)
- {
- mvec[0] = new MachineInstr(ChooseMulInstruction(subtreeRoot,
- checkCast));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
- }
- else
- if (mvec[1] != NULL)
- ++numInstr;
+ {
+ MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
+ ? FSMULD
+ : INVALID_MACHINE_OPCODE);
+ CreateMulInstruction(target,
+ subtreeRoot->leftChild()->getValue(),
+ subtreeRoot->rightChild()->getValue(),
+ subtreeRoot->getInstruction(),
+ mvec, forceOp);
break;
-
+ }
case 236: // reg: Div(reg, Constant)
- mvec[0] = CreateDivConstInstruction(target, subtreeRoot, mvec[1]);
- if (mvec[0] != NULL)
- {
- if (mvec[1] != NULL)
- ++numInstr;
- }
- else
+ L = mvec.size();
+ CreateDivConstInstruction(target, subtreeRoot, mvec);
+ if (mvec.size() > L)
+ break;
// ELSE FALL THROUGH
-
+
case 36: // reg: Div(reg, reg)
- mvec[0] = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseDivInstruction(target, subtreeRoot)));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 37: // reg: Rem(reg, reg)
@@ -1585,23 +1767,24 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
subtreeRoot->rightChild()->getValue());
MachineCodeForInstruction::get(remInstr).addTemp(quot).addTemp(prod);
- mvec[0] = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,quot);
+ M = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
+ Set3OperandsFromInstr(M, subtreeRoot, target);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,quot);
+ mvec.push_back(M);
- int n = numInstr++;
- mvec[n] = new MachineInstr(ChooseMulInstructionByType(
+ M = new MachineInstr(ChooseMulInstructionByType(
subtreeRoot->getInstruction()->getType()));
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,quot);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,quot);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
subtreeRoot->rightChild()->getValue());
- mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,prod);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,prod);
+ mvec.push_back(M);
- n = numInstr++;
- mvec[n] = new MachineInstr(ChooseSubInstructionByType(
+ M = new MachineInstr(ChooseSubInstructionByType(
subtreeRoot->getInstruction()->getType()));
- Set3OperandsFromInstr(mvec[n], subtreeRoot, target);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,prod);
+ Set3OperandsFromInstr(M, subtreeRoot, target);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,prod);
+ mvec.push_back(M);
break;
}
@@ -1610,42 +1793,42 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 238: // bool: And(bool, boolconst)
case 338: // reg : BAnd(reg, reg)
case 538: // reg : BAnd(reg, Constant)
- mvec[0] = new MachineInstr(AND);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(AND));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 138: // bool: And(bool, not)
case 438: // bool: BAnd(bool, not)
- mvec[0] = new MachineInstr(ANDN);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ANDN));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 39: // bool: Or(bool, bool)
case 239: // bool: Or(bool, boolconst)
case 339: // reg : BOr(reg, reg)
case 539: // reg : BOr(reg, Constant)
- mvec[0] = new MachineInstr(ORN);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ORN));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 139: // bool: Or(bool, not)
case 439: // bool: BOr(bool, not)
- mvec[0] = new MachineInstr(ORN);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ORN));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 40: // bool: Xor(bool, bool)
case 240: // bool: Xor(bool, boolconst)
case 340: // reg : BXor(reg, reg)
case 540: // reg : BXor(reg, Constant)
- mvec[0] = new MachineInstr(XOR);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(XOR));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 140: // bool: Xor(bool, not)
case 440: // bool: BXor(bool, not)
- mvec[0] = new MachineInstr(XNOR);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(XNOR));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
case 41: // boolconst: SetCC(reg, Constant)
@@ -1672,8 +1855,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
(parentOpCode = minstrVec[0]->getOpCode()) >= BRZ &&
parentOpCode <= BRGEZ)
{
- numInstr = 0; // don't forward the operand!
- break;
+ break; // don't forward the operand!
}
}
// ELSE FALL THROUGH
@@ -1733,11 +1915,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// a separate instruction to compute the bool result, so discard
// result of SUBcc instruction anyway.
//
- mvec[0] = new MachineInstr(SUBcc);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target, ! keepSubVal);
-
- mvec[0]->SetMachineOperand(3, MachineOperand::MO_CCRegister,
- tmpForCC, /*def*/true);
+ M = new MachineInstr(SUBcc);
+ Set3OperandsFromInstr(M, subtreeRoot, target, ! keepSubVal);
+ M->SetMachineOperandVal(3, MachineOperand::MO_CCRegister,
+ tmpForCC, /*def*/true);
+ mvec.push_back(M);
if (computeBoolVal)
{ // recompute bool using the integer condition codes
@@ -1748,13 +1930,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
else
{
// FP condition: dest of FCMP should be some FCCn register
- mvec[0] = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
+ M = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
tmpForCC);
- mvec[0]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
+ M->SetMachineOperandVal(1,MachineOperand::MO_VirtualRegister,
subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,
+ M->SetMachineOperandVal(2,MachineOperand::MO_VirtualRegister,
subtreeRoot->rightChild()->getValue());
+ mvec.push_back(M);
if (computeBoolVal)
{// recompute bool using the FP condition codes
@@ -1768,39 +1951,38 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{
if (mustClearReg)
{// Unconditionally set register to 0
- int n = numInstr++;
- mvec[n] = new MachineInstr(SETHI);
- mvec[n]->SetMachineOperand(0,MachineOperand::MO_UnextendedImmed,
- (int64_t)0);
- mvec[n]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
- setCCInstr);
+ M = new MachineInstr(SETHI);
+ M->SetMachineOperandConst(0,MachineOperand::MO_UnextendedImmed,
+ (int64_t)0);
+ M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+ setCCInstr);
+ mvec.push_back(M);
}
// Now conditionally move `valueToMove' (0 or 1) into the register
- int n = numInstr++;
- mvec[n] = new MachineInstr(movOpCode);
- mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
- tmpForCC);
- mvec[n]->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
- valueToMove);
- mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- setCCInstr);
+ M = new MachineInstr(movOpCode);
+ M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+ tmpForCC);
+ M->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
+ valueToMove);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ setCCInstr);
+ mvec.push_back(M);
}
break;
}
case 43: // boolreg: VReg
case 44: // boolreg: Constant
- numInstr = 0;
break;
case 51: // reg: Load(reg)
case 52: // reg: Load(ptrreg)
case 53: // reg: LoadIdx(reg,reg)
case 54: // reg: LoadIdx(ptrreg,reg)
- mvec[0] = new MachineInstr(ChooseLoadInstruction(
- subtreeRoot->getValue()->getType()));
- SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ChooseLoadInstruction(
+ subtreeRoot->getValue()->getType())));
+ SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
break;
case 55: // reg: GetElemPtr(reg)
@@ -1824,100 +2006,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
cast<PointerType>(getElemInst->getPointerOperand()->getType());
if (! ptrType->getElementType()->isArrayType())
{// we don't need a separate instr
- numInstr = 0; // don't forward operand!
- break;
+ break; // don't forward operand!
}
}
}
// else in all other cases we need to a separate ADD instruction
- mvec[0] = new MachineInstr(ADD);
- SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr(ADD));
+ SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
break;
case 57: // reg: Alloca: Implement as 1 instruction:
{ // add %fp, offsetFromFP -> result
- Instruction* instr = subtreeRoot->getInstruction();
- const PointerType* instrType = (const PointerType*) instr->getType();
- assert(instrType->isPointerType());
- int tsize = (int)
- target.findOptimalStorageSize(instrType->getElementType());
- assert(tsize != 0 && "Just to check when this can happen");
-
- Method* method = instr->getParent()->getParent();
- MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
- int offsetFromFP = mcInfo.allocateLocalVar(target, instr, (unsigned int) tsize);
-
- // Create a temporary Value to hold the constant offset.
- // This is needed because it may not fit in the immediate field.
- ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP);
-
- // Instruction 1: add %fp, offsetFromFP -> result
- mvec[0] = new MachineInstr(ADD);
- mvec[0]->SetMachineOperand(0, target.getRegInfo().getFramePointer());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- offsetVal);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- instr);
+ AllocationInst* instr = cast<AllocationInst>(subtreeRoot->getInstruction());
+ unsigned int tsize =target.findOptimalStorageSize(instr->getAllocatedType());
+ assert(tsize != 0);
+ CreateCodeForFixedSizeAlloca(target, instr, tsize, 1, mvec);
break;
}
-
+
case 58: // reg: Alloca(reg): Implement as 3 instructions:
// mul num, typeSz -> tmp
// sub %sp, tmp -> %sp
{ // add %sp, frameSizeBelowDynamicArea -> result
- Instruction* instr = subtreeRoot->getInstruction();
- const PointerType* instrType = (const PointerType*) instr->getType();
- assert(instrType->isPointerType() &&
- instrType->getElementType()->isArrayType());
- const Type* eltType =
- ((ArrayType*) instrType->getElementType())->getElementType();
- int tsize = (int) target.findOptimalStorageSize(eltType);
-
- assert(tsize != 0 && "Just to check when this can happen");
-
- // Create a temporary Value to hold the constant type-size
- ConstantSInt* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
-
- // Create a temporary Value to hold the constant offset from SP
- Method* method = instr->getParent()->getParent();
- bool ignore; // we don't need this
- ConstantSInt* dynamicAreaOffset = ConstantSInt::get(Type::IntTy,
- target.getFrameInfo().getDynamicAreaOffset(MachineCodeForMethod::get(method),
- ignore));
+ AllocationInst* instr = cast<AllocationInst>(subtreeRoot->getInstruction());
+ const Type* eltType = instr->getAllocatedType();
- // Create a temporary value to hold `tmp'
- Instruction* tmpInstr = new TmpInstruction(
- subtreeRoot->leftChild()->getValue(),
- NULL /*could insert tsize here*/);
- MachineCodeForInstruction::get(subtreeRoot->getInstruction()).addTemp(tmpInstr);
-
- // Instruction 1: mul numElements, typeSize -> tmp
- mvec[0] = new MachineInstr(MULX);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- subtreeRoot->leftChild()->getValue());
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- tsizeVal);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- tmpInstr);
-
- // Instruction 2: sub %sp, tmp -> %sp
- numInstr++;
- mvec[1] = new MachineInstr(SUB);
- mvec[1]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
- mvec[1]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- tmpInstr);
- mvec[1]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
-
- // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
- numInstr++;
- mvec[2] = new MachineInstr(ADD);
- mvec[2]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
- mvec[2]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
- dynamicAreaOffset);
- mvec[2]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,instr);
+ // If the #elements is a constant, use simpler code for fixed-size allocas
+ int tsize = (int) target.findOptimalStorageSize(eltType);
+ if (isa<Constant>(instr->getArraySize()))
+ // total size is constant: generate code for fixed-size alloca
+ CreateCodeForFixedSizeAlloca(target, instr, tsize,
+ cast<ConstantUInt>(instr->getArraySize())->getValue(), mvec);
+ else // total size is not constant.
+ CreateCodeForVariableSizeAlloca(target, instr, tsize,
+ instr->getArraySize(), mvec);
break;
}
-
+
case 61: // reg: Call
{ // Generate a call-indirect (i.e., jmpl) for now to expose
// the potential need for registers. If an absolute address
@@ -1948,34 +2073,37 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
//
if (callee->getValueType() == Value::MethodVal)
{ // direct function call
- mvec[0] = new MachineInstr(CALL);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,
- callee);
+ M = new MachineInstr(CALL);
+ M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
+ callee);
}
else
{ // indirect function call
- mvec[0] = new MachineInstr(JMPLCALL);
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
- callee);
- mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
- (int64_t) 0);
- mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
- retAddrReg);
+ M = new MachineInstr(JMPLCALL);
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+ callee);
+ M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
+ (int64_t) 0);
+ M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+ retAddrReg);
}
+ mvec.push_back(M);
+
// Add the call operands and return value as implicit refs
for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
if (callInstr->getOperand(i) != callee)
- mvec[0]->addImplicitRef(callInstr->getOperand(i));
+ mvec.back()->addImplicitRef(callInstr->getOperand(i));
if (callInstr->getType() != Type::VoidTy)
- mvec[0]->addImplicitRef(callInstr, /*isDef*/ true);
+ mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);
// For the CALL instruction, the ret. addr. reg. is also implicit
if (callee->getValueType() == Value::MethodVal)
- mvec[0]->addImplicitRef(retAddrReg, /*isDef*/ true);
+ mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true);
- mvec[numInstr++] = new MachineInstr(NOP); // delay slot
+ // delay slot
+ mvec.push_back(new MachineInstr(NOP));
break;
}
@@ -1984,8 +2112,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
assert(opType->isIntegral()
|| opType == Type::BoolTy
|| opType->isPointerType()&& "Shl unsupported for other types");
- mvec[0] = new MachineInstr((opType == Type::LongTy)? SLLX : SLL);
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr((opType == Type::LongTy)? SLLX : SLL));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
}
@@ -1994,38 +2122,38 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
assert(opType->isIntegral()
|| opType == Type::BoolTy
|| opType->isPointerType() &&"Shr unsupported for other types");
- mvec[0] = new MachineInstr((opType->isSigned()
- ? ((opType == Type::LongTy)? SRAX : SRA)
- : ((opType == Type::LongTy)? SRLX : SRL)));
- Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+ mvec.push_back(new MachineInstr((opType->isSigned()
+ ? ((opType == Type::LongTy)? SRAX : SRA)
+ : ((opType == Type::LongTy)? SRLX : SRL))));
+ Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
break;
}
case 64: // reg: Phi(reg,reg)
- numInstr = 0; // don't forward the value
- break;
+ break; // don't forward the value
+
#undef NEED_PHI_MACHINE_INSTRS
#ifdef NEED_PHI_MACHINE_INSTRS
{ // This instruction has variable #operands, so resultPos is 0.
Instruction* phi = subtreeRoot->getInstruction();
- mvec[0] = new MachineInstr(PHI, 1 + phi->getNumOperands());
- mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ M = new MachineInstr(PHI, 1 + phi->getNumOperands());
+ M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
subtreeRoot->getValue());
for (unsigned i=0, N=phi->getNumOperands(); i < N; i++)
- mvec[0]->SetMachineOperand(i+1, MachineOperand::MO_VirtualRegister,
- phi->getOperand(i));
+ M->SetMachineOperandVal(i+1, MachineOperand::MO_VirtualRegister,
+ phi->getOperand(i));
+ mvec.push_back(M);
break;
}
#endif // NEED_PHI_MACHINE_INSTRS
+
case 71: // reg: VReg
case 72: // reg: Constant
- numInstr = 0; // don't forward the value
- break;
+ break; // don't forward the value
default:
assert(0 && "Unrecognized BURG rule");
- numInstr = 0;
break;
}
}
@@ -2040,16 +2168,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
else
{
vector<MachineInstr*> minstrVec;
- target.getInstrInfo().CreateCopyInstructionsByType(target,
+ target.getInstrInfo().CreateCopyInstructionsByType(target,
+ subtreeRoot->getInstruction()->getParent()->getParent(),
subtreeRoot->getInstruction()->getOperand(forwardOperandNum),
subtreeRoot->getInstruction(), minstrVec);
assert(minstrVec.size() > 0);
- for (unsigned i=0; i < minstrVec.size(); ++i)
- mvec[numInstr++] = minstrVec[i];
+ mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
}
}
-
- return numInstr;
}