Insert copy operations for FP arguments to a varargs function,

to copy the FP arg. to an integer.  Necessary so that the
register allocator has two different live ranges for the FP value
and the int. argument.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2314 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve 2002-04-25 04:37:51 +00:00
parent a4a943dd5a
commit dbc4fad577

View File

@ -239,12 +239,11 @@ ChooseMovpccAfterSub(const InstructionNode* instrNode,
} }
static inline MachineOpCode static inline MachineOpCode
ChooseConvertToFloatInstr(const InstructionNode* instrNode, ChooseConvertToFloatInstr(OpLabel vopCode, const Type* opType)
const Type* opType)
{ {
MachineOpCode opCode = INVALID_OPCODE; MachineOpCode opCode = INVALID_OPCODE;
switch(instrNode->getOpLabel()) switch(vopCode)
{ {
case ToFloatTy: case ToFloatTy:
if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy) if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
@ -285,14 +284,11 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
} }
static inline MachineOpCode static inline MachineOpCode
ChooseConvertToIntInstr(const InstructionNode* instrNode, ChooseConvertToIntInstr(OpLabel vopCode, const Type* opType)
const Type* opType)
{ {
MachineOpCode opCode = INVALID_OPCODE;; MachineOpCode opCode = INVALID_OPCODE;;
int instrType = (int) instrNode->getOpLabel(); if (vopCode == ToSByteTy || vopCode == ToShortTy || vopCode == ToIntTy)
if (instrType == ToSByteTy || instrType == ToShortTy || instrType == ToIntTy)
{ {
switch (opType->getPrimitiveID()) switch (opType->getPrimitiveID())
{ {
@ -303,7 +299,7 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
break; break;
} }
} }
else if (instrType == ToLongTy) else if (vopCode == ToLongTy)
{ {
switch (opType->getPrimitiveID()) switch (opType->getPrimitiveID())
{ {
@ -320,6 +316,17 @@ ChooseConvertToIntInstr(const InstructionNode* instrNode,
return opCode; return opCode;
} }
MachineInstr*
CreateConvertToIntInstr(OpLabel vopCode, Value* srcVal, Value* destVal)
{
MachineOpCode opCode = ChooseConvertToIntInstr(vopCode, srcVal->getType());
assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
MachineInstr* M = new MachineInstr(opCode);
M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, srcVal);
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, destVal);
return M;
}
static inline MachineOpCode static inline MachineOpCode
ChooseAddInstructionByType(const Type* resultType) ChooseAddInstructionByType(const Type* resultType)
@ -1565,9 +1572,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
(dest->getType() == Type::LongTy)? Type::DoubleTy (dest->getType() == Type::LongTy)? Type::DoubleTy
: Type::FloatTy; : Type::FloatTy;
destForCast = new TmpInstruction(destTypeToUse, leftVal); destForCast = new TmpInstruction(destTypeToUse, leftVal);
MachineCodeForInstruction &MCFI = MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(dest); MachineCodeForInstruction::get(dest);
MCFI.addTemp(destForCast); destMCFI.addTemp(destForCast);
vector<TmpInstruction*> tempVec; vector<TmpInstruction*> tempVec;
target.getInstrInfo().CreateCodeToCopyFloatToInt( target.getInstrInfo().CreateCodeToCopyFloatToInt(
@ -1576,19 +1583,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
minstrVec, tempVec, target); minstrVec, tempVec, target);
for (unsigned i=0; i < tempVec.size(); ++i) for (unsigned i=0; i < tempVec.size(); ++i)
MCFI.addTemp(tempVec[i]); destMCFI.addTemp(tempVec[i]);
} }
else else
destForCast = leftVal; destForCast = leftVal;
MachineOpCode opCode=ChooseConvertToIntInstr(subtreeRoot, opType); M = CreateConvertToIntInstr(subtreeRoot->getOpLabel(),
assert(opCode != INVALID_OPCODE && "Expected to need conversion!"); leftVal, destForCast);
M = new MachineInstr(opCode);
M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
leftVal);
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
destForCast);
mvec.push_back(M); mvec.push_back(M);
// Append the copy code, if any, after the conversion instr. // Append the copy code, if any, after the conversion instr.
@ -1616,7 +1617,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ {
Value* leftVal = subtreeRoot->leftChild()->getValue(); Value* leftVal = subtreeRoot->leftChild()->getValue();
const Type* opType = leftVal->getType(); const Type* opType = leftVal->getType();
MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType); MachineOpCode opCode=ChooseConvertToFloatInstr(
subtreeRoot->getOpLabel(), opType);
if (opCode == INVALID_OPCODE) // no conversion needed if (opCode == INVALID_OPCODE) // no conversion needed
{ {
forwardOperandNum = 0; // forward first operand to user forwardOperandNum = 0; // forward first operand to user
@ -1641,9 +1643,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
: Type::FloatTy; : Type::FloatTy;
srcForCast = new TmpInstruction(srcTypeToUse, dest); srcForCast = new TmpInstruction(srcTypeToUse, dest);
MachineCodeForInstruction &DestMCFI = MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(dest); MachineCodeForInstruction::get(dest);
DestMCFI.addTemp(srcForCast); destMCFI.addTemp(srcForCast);
vector<MachineInstr*> minstrVec; vector<MachineInstr*> minstrVec;
vector<TmpInstruction*> tempVec; vector<TmpInstruction*> tempVec;
@ -1655,7 +1657,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end()); mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end());
for (unsigned i=0; i < tempVec.size(); ++i) for (unsigned i=0; i < tempVec.size(); ++i)
DestMCFI.addTemp(tempVec[i]); destMCFI.addTemp(tempVec[i]);
} }
else else
srcForCast = leftVal; srcForCast = leftVal;
@ -2003,14 +2005,16 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
} }
case 61: // reg: Call case 61: // reg: Call
{ // Generate a call-indirect (i.e., jmpl) for now to expose { // Generate a direct (CALL) or indirect (JMPL). depending
// the potential need for registers. If an absolute address // Mark the return-address register and the indirection
// is available, replace this with a CALL instruction. // register (if any) as hidden virtual registers.
// Mark both the indirection register and the return-address
// register as hidden virtual registers.
// Also, mark the operands of the Call and return value (if // Also, mark the operands of the Call and return value (if
// any) as implicit operands of the CALL machine instruction. // any) as implicit operands of the CALL machine instruction.
// //
// If this is a varargs function, floating point arguments
// have to passed in integer registers so insert
// copy-float-to-int instructions for each float operand.
//
CallInst *callInstr = cast<CallInst>(subtreeRoot->getInstruction()); CallInst *callInstr = cast<CallInst>(subtreeRoot->getInstruction());
Value *callee = callInstr->getCalledValue(); Value *callee = callInstr->getCalledValue();
@ -2048,9 +2052,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// in register allocation. // in register allocation.
// //
// Add the call operands and return value as implicit refs // Add the call operands and return value as implicit refs
// const Type* funcType = isa<Function>(callee)? callee->getType()
// : cast<PointerType>(callee->getType())->getElementType();
const Type* funcType = callee->getType();
bool isVarArgs = cast<FunctionType>(cast<PointerType>(funcType)
->getElementType())->isVarArg();
for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i) for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
if (callInstr->getOperand(i) != callee) if (callInstr->getOperand(i) != callee)
mvec.back()->addImplicitRef(callInstr->getOperand(i)); {
Value* argVal = callInstr->getOperand(i);
// Check for FP arguments to varargs functions
if (isVarArgs && argVal->getType()->isFloatingPoint())
{ // Add a copy-float-to-int instruction
MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(callInstr);
Instruction* intArgReg =
new TmpInstruction(Type::IntTy, argVal);
destMCFI.addTemp(intArgReg);
vector<MachineInstr*> minstrVec;
vector<TmpInstruction*> tempVec;
target.getInstrInfo().CreateCodeToCopyFloatToInt(
callInstr->getParent()->getParent(),
argVal, (TmpInstruction*) intArgReg,
minstrVec, tempVec, target);
mvec.insert(mvec.begin(), minstrVec.begin(),minstrVec.end());
for (unsigned i=0; i < tempVec.size(); ++i)
destMCFI.addTemp(tempVec[i]);
argVal = intArgReg;
}
mvec.back()->addImplicitRef(argVal);
}
if (callInstr->getType() != Type::VoidTy) if (callInstr->getType() != Type::VoidTy)
mvec.back()->addImplicitRef(callInstr, /*isDef*/ true); mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);