mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
When a node value is only used by a CopyToReg, use the user's dest. This should not be restricted to nodes that produce only a single value.
llvm-svn: 38485
This commit is contained in:
parent
23dc96f640
commit
cf3b1c89a9
@ -240,7 +240,7 @@ namespace llvm {
|
||||
/// VRBaseMap contains, for each already emitted node, the first virtual
|
||||
/// register number for the results of the node.
|
||||
///
|
||||
void EmitNode(SDNode *Node, DenseMap<SDNode*, unsigned> &VRBaseMap);
|
||||
void EmitNode(SDNode *Node, DenseMap<SDOperand, unsigned> &VRBaseMap);
|
||||
|
||||
/// EmitNoop - Emit a noop instruction.
|
||||
///
|
||||
@ -257,7 +257,7 @@ namespace llvm {
|
||||
private:
|
||||
void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
|
||||
const TargetInstrDescriptor *II,
|
||||
DenseMap<SDNode*, unsigned> &VRBaseMap);
|
||||
DenseMap<SDOperand, unsigned> &VRBaseMap);
|
||||
};
|
||||
|
||||
/// createBFS_DAGScheduler - This creates a simple breadth first instruction
|
||||
|
@ -254,31 +254,54 @@ static const TargetRegisterClass *getInstrOperandRegClass(
|
||||
? TII->getPointerRegClass() : MRI->getRegClass(toi.RegClass);
|
||||
}
|
||||
|
||||
static unsigned CreateVirtualRegisters(const MRegisterInfo *MRI,
|
||||
MachineInstr *MI,
|
||||
static void CreateVirtualRegisters(SDNode *Node,
|
||||
unsigned NumResults,
|
||||
const MRegisterInfo *MRI,
|
||||
MachineInstr *MI,
|
||||
SSARegMap *RegMap,
|
||||
const TargetInstrInfo *TII,
|
||||
const TargetInstrDescriptor &II) {
|
||||
const TargetInstrDescriptor &II,
|
||||
DenseMap<SDOperand, unsigned> &VRBaseMap) {
|
||||
for (unsigned i = 0; i < NumResults; ++i) {
|
||||
// If the specific node value is only used by a CopyToReg and the dest reg
|
||||
// is a vreg, use the CopyToReg'd destination register instead of creating
|
||||
// a new vreg.
|
||||
unsigned VRBase = 0;
|
||||
for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
|
||||
UI != E; ++UI) {
|
||||
SDNode *Use = *UI;
|
||||
if (Use->getOpcode() == ISD::CopyToReg &&
|
||||
Use->getOperand(2).Val == Node &&
|
||||
Use->getOperand(2).ResNo == i) {
|
||||
unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
|
||||
if (MRegisterInfo::isVirtualRegister(Reg)) {
|
||||
VRBase = Reg;
|
||||
MI->addRegOperand(Reg, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (VRBase == 0) {
|
||||
// Create the result registers for this node and add the result regs to
|
||||
// the machine instruction.
|
||||
unsigned ResultReg =
|
||||
RegMap->createVirtualRegister(getInstrOperandRegClass(MRI, TII, &II, 0));
|
||||
MI->addRegOperand(ResultReg, true);
|
||||
for (unsigned i = 1; i != NumResults; ++i) {
|
||||
const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, &II, i);
|
||||
assert(RC && "Isn't a register operand!");
|
||||
MI->addRegOperand(RegMap->createVirtualRegister(RC), true);
|
||||
VRBase = RegMap->createVirtualRegister(RC);
|
||||
MI->addRegOperand(VRBase, true);
|
||||
}
|
||||
|
||||
bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,i), VRBase));
|
||||
assert(isNew && "Node emitted out of order - early");
|
||||
}
|
||||
return ResultReg;
|
||||
}
|
||||
|
||||
/// getVR - Return the virtual register corresponding to the specified result
|
||||
/// of the specified node.
|
||||
static unsigned getVR(SDOperand Op, DenseMap<SDNode*, unsigned> &VRBaseMap) {
|
||||
DenseMap<SDNode*, unsigned>::iterator I = VRBaseMap.find(Op.Val);
|
||||
static unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap) {
|
||||
DenseMap<SDOperand, unsigned>::iterator I = VRBaseMap.find(Op);
|
||||
assert(I != VRBaseMap.end() && "Node emitted out of order - late");
|
||||
return I->second + Op.ResNo;
|
||||
return I->second;
|
||||
}
|
||||
|
||||
|
||||
@ -289,7 +312,7 @@ static unsigned getVR(SDOperand Op, DenseMap<SDNode*, unsigned> &VRBaseMap) {
|
||||
void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
|
||||
unsigned IIOpNum,
|
||||
const TargetInstrDescriptor *II,
|
||||
DenseMap<SDNode*, unsigned> &VRBaseMap) {
|
||||
DenseMap<SDOperand, unsigned> &VRBaseMap) {
|
||||
if (Op.isTargetOpcode()) {
|
||||
// Note that this case is redundant with the final else block, but we
|
||||
// include it because it is the most common and it makes the logic
|
||||
@ -406,9 +429,7 @@ static const TargetRegisterClass *getPhysicalRegisterRegClass(
|
||||
/// EmitNode - Generate machine code for an node and needed dependencies.
|
||||
///
|
||||
void ScheduleDAG::EmitNode(SDNode *Node,
|
||||
DenseMap<SDNode*, unsigned> &VRBaseMap) {
|
||||
unsigned VRBase = 0; // First virtual register for node
|
||||
|
||||
DenseMap<SDOperand, unsigned> &VRBaseMap) {
|
||||
// If machine instruction
|
||||
if (Node->isTargetOpcode()) {
|
||||
unsigned Opc = Node->getTargetOpcode();
|
||||
@ -428,28 +449,9 @@ void ScheduleDAG::EmitNode(SDNode *Node,
|
||||
|
||||
// Add result register values for things that are defined by this
|
||||
// instruction.
|
||||
|
||||
// If the node is only used by a CopyToReg and the dest reg is a vreg, use
|
||||
// the CopyToReg'd destination register instead of creating a new vreg.
|
||||
if (NumResults == 1) {
|
||||
for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
|
||||
UI != E; ++UI) {
|
||||
SDNode *Use = *UI;
|
||||
if (Use->getOpcode() == ISD::CopyToReg &&
|
||||
Use->getOperand(2).Val == Node) {
|
||||
unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
|
||||
if (MRegisterInfo::isVirtualRegister(Reg)) {
|
||||
VRBase = Reg;
|
||||
MI->addRegOperand(Reg, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, create new virtual registers.
|
||||
if (NumResults && VRBase == 0)
|
||||
VRBase = CreateVirtualRegisters(MRI, MI, NumResults, RegMap, TII, II);
|
||||
if (NumResults)
|
||||
CreateVirtualRegisters(Node, NumResults, MRI, MI, RegMap,
|
||||
TII, II, VRBaseMap);
|
||||
|
||||
// Emit all of the actual operands of this instruction, adding them to the
|
||||
// instruction as appropriate.
|
||||
@ -510,9 +512,12 @@ void ScheduleDAG::EmitNode(SDNode *Node,
|
||||
break;
|
||||
}
|
||||
case ISD::CopyFromReg: {
|
||||
unsigned VRBase = 0;
|
||||
unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
|
||||
if (MRegisterInfo::isVirtualRegister(SrcReg)) {
|
||||
VRBase = SrcReg; // Just use the input register directly!
|
||||
// Just use the input register directly!
|
||||
bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,0),SrcReg));
|
||||
assert(isNew && "Node emitted out of order - early");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -542,6 +547,9 @@ void ScheduleDAG::EmitNode(SDNode *Node,
|
||||
VRBase = RegMap->createVirtualRegister(TRC);
|
||||
}
|
||||
MRI->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC);
|
||||
|
||||
bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,0), VRBase));
|
||||
assert(isNew && "Node emitted out of order - early");
|
||||
break;
|
||||
}
|
||||
case ISD::INLINEASM: {
|
||||
@ -604,9 +612,6 @@ void ScheduleDAG::EmitNode(SDNode *Node,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(!VRBaseMap.count(Node) && "Node emitted out of order - early");
|
||||
VRBaseMap[Node] = VRBase;
|
||||
}
|
||||
|
||||
void ScheduleDAG::EmitNoop() {
|
||||
@ -629,7 +634,7 @@ void ScheduleDAG::EmitSchedule() {
|
||||
|
||||
|
||||
// Finally, emit the code for all of the scheduled instructions.
|
||||
DenseMap<SDNode*, unsigned> VRBaseMap;
|
||||
DenseMap<SDOperand, unsigned> VRBaseMap;
|
||||
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
||||
if (SUnit *SU = Sequence[i]) {
|
||||
for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; j++)
|
||||
|
@ -682,7 +682,7 @@ void ScheduleDAGSimple::EmitAll() {
|
||||
LI->first, RegMap->getRegClass(LI->second));
|
||||
}
|
||||
|
||||
DenseMap<SDNode*, unsigned> VRBaseMap;
|
||||
DenseMap<SDOperand, unsigned> VRBaseMap;
|
||||
|
||||
// For each node in the ordering
|
||||
for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user