[llvm-commits] [llvm] r40710 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
Evan Cheng
evan.cheng at apple.com
Wed Aug 1 17:28:15 PDT 2007
Author: evancheng
Date: Wed Aug 1 19:28:15 2007
New Revision: 40710
URL: http://llvm.org/viewvc/llvm-project?rev=40710&view=rev
Log:
Instead of adding copyfromreg's to handle physical definitions. Now isel can
simply specify them as results and let scheduledag handle them. That
is, instead of
SDOperand Flag = DAG.getTargetNode(Opc, MVT::i32, MVT::Flag, ...)
SDOperand Result = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, Flag)
Just write:
SDOperand Result = DAG.getTargetNode(Opc, MVT::i32, MVT::i32, ...)
And let scheduledag emit the move from X86::EAX to a virtual register.
Modified:
llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Aug 1 19:28:15 2007
@@ -245,7 +245,16 @@
/// EmitNoop - Emit a noop instruction.
///
void EmitNoop();
+
+ /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
+ /// implicit physical register output.
+ void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned SrcReg,
+ DenseMap<SDOperand, unsigned> &VRBaseMap);
+ void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
+ const TargetInstrDescriptor &II,
+ DenseMap<SDOperand, unsigned> &VRBaseMap);
+
void EmitSchedule();
void dumpSchedule() const;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Aug 1 19:28:15 2007
@@ -254,15 +254,69 @@
? TII->getPointerRegClass() : MRI->getRegClass(toi.RegClass);
}
-static void CreateVirtualRegisters(SDNode *Node,
- unsigned NumResults,
- const MRegisterInfo *MRI,
- MachineInstr *MI,
- SSARegMap *RegMap,
- const TargetInstrInfo *TII,
- const TargetInstrDescriptor &II,
- DenseMap<SDOperand, unsigned> &VRBaseMap) {
- for (unsigned i = 0; i < NumResults; ++i) {
+// Returns the Register Class of a physical register
+static const TargetRegisterClass *getPhysicalRegisterRegClass(
+ const MRegisterInfo *MRI,
+ MVT::ValueType VT,
+ unsigned reg) {
+ assert(MRegisterInfo::isPhysicalRegister(reg) &&
+ "reg must be a physical register");
+ // Pick the register class of the right type that contains this physreg.
+ for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(),
+ E = MRI->regclass_end(); I != E; ++I)
+ if ((*I)->hasType(VT) && (*I)->contains(reg))
+ return *I;
+ assert(false && "Couldn't find the register class");
+ return 0;
+}
+
+void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned SrcReg,
+ DenseMap<SDOperand, unsigned> &VRBaseMap) {
+ unsigned VRBase = 0;
+ if (MRegisterInfo::isVirtualRegister(SrcReg)) {
+ // Just use the input register directly!
+ bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,ResNo),SrcReg));
+ assert(isNew && "Node emitted out of order - early");
+ return;
+ }
+
+ // 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.
+ 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 == ResNo) {
+ unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
+ if (MRegisterInfo::isVirtualRegister(DestReg)) {
+ VRBase = DestReg;
+ break;
+ }
+ }
+ }
+
+ // Figure out the register class to create for the destreg.
+ const TargetRegisterClass *TRC = 0;
+ if (VRBase) {
+ TRC = RegMap->getRegClass(VRBase);
+ } else {
+ TRC = getPhysicalRegisterRegClass(MRI, Node->getValueType(ResNo), SrcReg);
+
+ // Create the reg, emit the copy.
+ VRBase = RegMap->createVirtualRegister(TRC);
+ }
+ MRI->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC);
+
+ bool isNew = VRBaseMap.insert(std::make_pair(SDOperand(Node,ResNo), VRBase));
+ assert(isNew && "Node emitted out of order - early");
+}
+
+void ScheduleDAG::CreateVirtualRegisters(SDNode *Node,
+ MachineInstr *MI,
+ const TargetInstrDescriptor &II,
+ DenseMap<SDOperand, unsigned> &VRBaseMap) {
+ for (unsigned i = 0; i < II.numDefs; ++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.
@@ -282,9 +336,9 @@
}
}
+ // Create the result registers for this node and add the result regs to
+ // the machine instruction.
if (VRBase == 0) {
- // Create the result registers for this node and add the result regs to
- // the machine instruction.
const TargetRegisterClass *RC = getInstrOperandRegClass(MRI, TII, &II, i);
assert(RC && "Isn't a register operand!");
VRBase = RegMap->createVirtualRegister(RC);
@@ -413,22 +467,6 @@
}
-// Returns the Register Class of a physical register
-static const TargetRegisterClass *getPhysicalRegisterRegClass(
- const MRegisterInfo *MRI,
- MVT::ValueType VT,
- unsigned reg) {
- assert(MRegisterInfo::isPhysicalRegister(reg) &&
- "reg must be a physical register");
- // Pick the register class of the right type that contains this physreg.
- for (MRegisterInfo::regclass_iterator I = MRI->regclass_begin(),
- E = MRI->regclass_end(); I != E; ++I)
- if ((*I)->hasType(VT) && (*I)->contains(reg))
- return *I;
- assert(false && "Couldn't find the register class");
- return 0;
-}
-
// Returns the Register Class of a subregister
static const TargetRegisterClass *getSubRegisterRegClass(
const TargetRegisterClass *TRC,
@@ -591,9 +629,10 @@
unsigned NumResults = CountResults(Node);
unsigned NodeOperands = CountOperands(Node);
unsigned NumMIOperands = NodeOperands + NumResults;
+ bool HasPhysRegOuts = (NumResults > II.numDefs) && II.ImplicitDefs;
#ifndef NDEBUG
assert((unsigned(II.numOperands) == NumMIOperands ||
- (II.Flags & M_VARIABLE_OPS)) &&
+ HasPhysRegOuts || (II.Flags & M_VARIABLE_OPS)) &&
"#operands for dag node doesn't match .td file!");
#endif
@@ -603,13 +642,12 @@
// Add result register values for things that are defined by this
// instruction.
if (NumResults)
- CreateVirtualRegisters(Node, NumResults, MRI, MI, RegMap,
- TII, II, VRBaseMap);
+ CreateVirtualRegisters(Node, MI, II, VRBaseMap);
// Emit all of the actual operands of this instruction, adding them to the
// instruction as appropriate.
for (unsigned i = 0; i != NodeOperands; ++i)
- AddOperand(MI, Node->getOperand(i), i+NumResults, &II, VRBaseMap);
+ AddOperand(MI, Node->getOperand(i), i+II.numDefs, &II, VRBaseMap);
// Commute node if it has been determined to be profitable.
if (CommuteSet.count(Node)) {
@@ -633,6 +671,14 @@
// taking some custom action.
BB = DAG.getTargetLoweringInfo().InsertAtEndOfBasicBlock(MI, BB);
}
+
+ // Additional results must be an physical register def.
+ if (HasPhysRegOuts) {
+ for (unsigned i = II.numDefs; i < NumResults; ++i) {
+ unsigned Reg = II.ImplicitDefs[i - II.numDefs];
+ EmitCopyFromReg(Node, i, Reg, VRBaseMap);
+ }
+ }
} else {
switch (Node->getOpcode()) {
default:
@@ -665,44 +711,8 @@
break;
}
case ISD::CopyFromReg: {
- unsigned VRBase = 0;
unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
- if (MRegisterInfo::isVirtualRegister(SrcReg)) {
- // 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;
- }
-
- // 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.
- 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 DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
- if (MRegisterInfo::isVirtualRegister(DestReg)) {
- VRBase = DestReg;
- break;
- }
- }
- }
-
- // Figure out the register class to create for the destreg.
- const TargetRegisterClass *TRC = 0;
- if (VRBase) {
- TRC = RegMap->getRegClass(VRBase);
- } else {
- TRC = getPhysicalRegisterRegClass(MRI, Node->getValueType(0), SrcReg);
-
- // Create the reg, emit the copy.
- 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");
+ EmitCopyFromReg(Node, 0, SrcReg, VRBaseMap);
break;
}
case ISD::INLINEASM: {
More information about the llvm-commits
mailing list