Teach scheduler about REG_SEQUENCE.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102984 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-05-04 00:22:40 +00:00
parent d622b0b208
commit ba609c88a5
2 changed files with 44 additions and 2 deletions

View File

@ -451,8 +451,7 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
unsigned SubIdx = cast<ConstantSDNode>(N2)->getZExtValue();
const TargetRegisterClass *TRC = MRI->getRegClass(SubReg);
const TargetRegisterClass *SRC =
getSuperRegisterRegClass(TRC, SubIdx,
Node->getValueType(0));
getSuperRegisterRegClass(TRC, SubIdx, Node->getValueType(0));
// Figure out the register class to create for the destreg.
// Note that if we're going to directly use an existing register,
@ -515,6 +514,40 @@ InstrEmitter::EmitCopyToRegClassNode(SDNode *Node,
assert(isNew && "Node emitted out of order - early");
}
/// EmitRegSequence - Generate machine code for REG_SEQUENCE nodes.
///
void InstrEmitter::EmitRegSequence(SDNode *Node,
DenseMap<SDValue, unsigned> &VRBaseMap) {
const TargetRegisterClass *RC = TLI->getRegClassFor(Node->getValueType(0));
unsigned NewVReg = MRI->createVirtualRegister(RC);
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
TII->get(TargetOpcode::REG_SEQUENCE), NewVReg);
unsigned NumOps = Node->getNumOperands();
assert((NumOps & 1) == 0 &&
"REG_SEQUENCE must have an even number of operands!");
const TargetInstrDesc &II = TII->get(TargetOpcode::REG_SEQUENCE);
for (unsigned i = 0; i != NumOps; ++i) {
SDValue Op = Node->getOperand(i);
#ifndef NDEBUG
if (i & 1) {
unsigned SubIdx = cast<ConstantSDNode>(Op)->getZExtValue();
unsigned SubReg = getVR(Node->getOperand(i-1), VRBaseMap);
const TargetRegisterClass *TRC = MRI->getRegClass(SubReg);
const TargetRegisterClass *SRC =
getSuperRegisterRegClass(TRC, SubIdx, Node->getValueType(0));
assert(SRC == RC && "Invalid subregister index in REG_SEQUENCE");
}
#endif
AddOperand(MI, Op, i+1, &II, VRBaseMap);
}
MBB->insert(InsertPos, MI);
SDValue Op(Node, 0);
bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second;
isNew = isNew; // Silence compiler warning.
assert(isNew && "Node emitted out of order - early");
}
/// EmitDbgValue - Generate machine instruction for a dbg_value node.
///
MachineInstr *
@ -589,6 +622,12 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
return;
}
// Handle REG_SEQUENCE specially.
if (Opc == TargetOpcode::REG_SEQUENCE) {
EmitRegSequence(Node, VRBaseMap);
return;
}
if (Opc == TargetOpcode::IMPLICIT_DEF)
// We want a unique VR for each IMPLICIT_DEF use.
return;

View File

@ -88,6 +88,9 @@ class InstrEmitter {
void EmitCopyToRegClassNode(SDNode *Node,
DenseMap<SDValue, unsigned> &VRBaseMap);
/// EmitRegSequence - Generate machine code for REG_SEQUENCE nodes.
///
void EmitRegSequence(SDNode *Node, DenseMap<SDValue, unsigned> &VRBaseMap);
public:
/// CountResults - The results of target nodes have register or immediate
/// operands first, then an optional chain, and optional flag operands