[llvm-commits] [llvm] r49164 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp

Evan Cheng evan.cheng at apple.com
Thu Apr 3 09:36:08 PDT 2008


Author: evancheng
Date: Thu Apr  3 11:36:07 2008
New Revision: 49164

URL: http://llvm.org/viewvc/llvm-project?rev=49164&view=rev
Log:
Start of a series of patches related to implicit_def.
There is no point in creating a long live range defined by an implicit_def. Scheduler now duplicates implicit_def instruction for each of its uses. Therefore, if an implicit_def node has multiple uses, it will become a number of very short live ranges, rather than a long one. This will make coalescer's job easier.

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=49164&r1=49163&r2=49164&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Thu Apr  3 11:36:07 2008
@@ -35,6 +35,7 @@
   class SelectionDAGISel;
   class TargetInstrInfo;
   class TargetInstrDesc;
+  class TargetLowering;
   class TargetMachine;
   class TargetRegisterClass;
 
@@ -246,6 +247,7 @@
     const TargetMachine &TM;              // Target processor
     const TargetInstrInfo *TII;           // Target instruction information
     const TargetRegisterInfo *TRI;        // Target processor register info
+    TargetLowering *TLI;                  // Target lowering info
     MachineFunction *MF;                  // Machine function
     MachineRegisterInfo &MRI;             // Virtual/real register map
     MachineConstantPool *ConstPool;       // Target constant pool
@@ -337,6 +339,34 @@
     ///
     void EmitNoop();
 
+    void EmitSchedule();
+
+    void dumpSchedule() const;
+
+    /// Schedule - Order nodes according to selected style.
+    ///
+    virtual void Schedule() {}
+
+  private:
+    /// EmitSubregNode - Generate machine code for subreg nodes.
+    ///
+    void EmitSubregNode(SDNode *Node, 
+                        DenseMap<SDOperand, unsigned> &VRBaseMap);
+
+    /// getVR - Return the virtual register corresponding to the specified result
+    /// of the specified node.
+    unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap);
+  
+    /// getDstOfCopyToRegUse - If the only use of the specified result number of
+    /// node is a CopyToReg, return its destination register. Return 0 otherwise.
+    unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
+
+    void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
+                    const TargetInstrDesc *II,
+                    DenseMap<SDOperand, unsigned> &VRBaseMap);
+
+    void AddMemOperand(MachineInstr *MI, const MemOperand &MO);
+
     void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
 
     /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
@@ -362,26 +392,6 @@
     /// and if it has live ins that need to be copied into vregs, emit the
     /// copies into the top of the block.
     void EmitLiveInCopies(MachineBasicBlock *MBB);
-
-    void EmitSchedule();
-
-    void dumpSchedule() const;
-
-    /// Schedule - Order nodes according to selected style.
-    ///
-    virtual void Schedule() {}
-
-  private:
-    /// EmitSubregNode - Generate machine code for subreg nodes.
-    ///
-    void EmitSubregNode(SDNode *Node, 
-                        DenseMap<SDOperand, unsigned> &VRBaseMap);
-  
-    void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
-                    const TargetInstrDesc *II,
-                    DenseMap<SDOperand, unsigned> &VRBaseMap);
-
-    void AddMemOperand(MachineInstr *MI, const MemOperand &MO);
   };
 
   /// createBURRListDAGScheduler - This creates a bottom up register usage

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=49164&r1=49163&r2=49164&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Thu Apr  3 11:36:07 2008
@@ -19,6 +19,7 @@
 #include "llvm/CodeGen/ScheduleDAG.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
@@ -42,10 +43,11 @@
 ScheduleDAG::ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
                          const TargetMachine &tm)
   : DAG(dag), BB(bb), TM(tm), MRI(BB->getParent()->getRegInfo()) {
-    TII = TM.getInstrInfo();
-    MF  = &DAG.getMachineFunction();
-    TRI = TM.getRegisterInfo();
-    ConstPool = BB->getParent()->getConstantPool();
+  TII = TM.getInstrInfo();
+  MF  = &DAG.getMachineFunction();
+  TRI = TM.getRegisterInfo();
+  TLI = &DAG.getTargetLoweringInfo();
+  ConstPool = BB->getParent()->getConstantPool();
 }
 
 /// CheckForPhysRegDependency - Check if the dependency between def and use of
@@ -447,8 +449,7 @@
   if (VRBase) {
     DstRC = MRI.getRegClass(VRBase);
   } else {
-    DstRC = DAG.getTargetLoweringInfo()
-             .getRegClassFor(Node->getValueType(ResNo));
+    DstRC = TLI->getRegClassFor(Node->getValueType(ResNo));
   }
     
   // If all uses are reading from the src physical register and copying the
@@ -467,9 +468,30 @@
   assert(isNew && "Node emitted out of order - early");
 }
 
+/// getDstOfCopyToRegUse - If the only use of the specified result number of
+/// node is a CopyToReg, return its destination register. Return 0 otherwise.
+unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node,
+                                               unsigned ResNo) const {
+  if (!Node->hasOneUse())
+    return 0;
+
+  SDNode *Use = *Node->use_begin();
+  if (Use->getOpcode() == ISD::CopyToReg && 
+      Use->getOperand(2).Val == Node &&
+      Use->getOperand(2).ResNo == ResNo) {
+    unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
+    if (TargetRegisterInfo::isVirtualRegister(Reg))
+      return Reg;
+  }
+  return 0;
+}
+
 void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
-                                         const TargetInstrDesc &II,
-                                     DenseMap<SDOperand, unsigned> &VRBaseMap) {
+                                 const TargetInstrDesc &II,
+                                 DenseMap<SDOperand, unsigned> &VRBaseMap) {
+  assert(Node->getTargetOpcode() != TargetInstrInfo::IMPLICIT_DEF &&
+         "IMPLICIT_DEF should have been handled as a special case elsewhere!");
+
   for (unsigned i = 0; i < II.getNumDefs(); ++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
@@ -493,13 +515,7 @@
     // Create the result registers for this node and add the result regs to
     // the machine instruction.
     if (VRBase == 0) {
-      const TargetRegisterClass *RC;
-      if (Node->getTargetOpcode() == TargetInstrInfo::IMPLICIT_DEF)
-        // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc
-        // does not include operand register class info.
-        RC = DAG.getTargetLoweringInfo().getRegClassFor(Node->getValueType(0));
-      else
-        RC = getInstrOperandRegClass(TRI, TII, II, i);
+      const TargetRegisterClass *RC = getInstrOperandRegClass(TRI, TII, II, i);
       assert(RC && "Isn't a register operand!");
       VRBase = MRI.createVirtualRegister(RC);
       MI->addOperand(MachineOperand::CreateReg(VRBase, true));
@@ -512,7 +528,22 @@
 
 /// getVR - Return the virtual register corresponding to the specified result
 /// of the specified node.
-static unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap) {
+unsigned ScheduleDAG::getVR(SDOperand Op,
+                            DenseMap<SDOperand, unsigned> &VRBaseMap) {
+  if (Op.isTargetOpcode() &&
+      Op.getTargetOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
+    // Add an IMPLICIT_DEF instruction before every use.
+    unsigned VReg = getDstOfOnlyCopyToRegUse(Op.Val, Op.ResNo);
+    // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc
+    // does not include operand register class info.
+    if (!VReg) {
+      const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType());
+      VReg = MRI.createVirtualRegister(RC);
+    }
+    BuildMI(BB, TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg);
+    return VReg;
+  }
+
   DenseMap<SDOperand, unsigned>::iterator I = VRBaseMap.find(Op);
   assert(I != VRBaseMap.end() && "Node emitted out of order - late");
   return I->second;
@@ -534,12 +565,11 @@
     assert(Op.getValueType() != MVT::Other &&
            Op.getValueType() != MVT::Flag &&
            "Chain and flag operands should occur at end of operand list!");
-    
     // Get/emit the operand.
     unsigned VReg = getVR(Op, VRBaseMap);
     const TargetInstrDesc &TID = MI->getDesc();
-    bool isOptDef = (IIOpNum < TID.getNumOperands())
-      ? (TID.OpInfo[IIOpNum].isOptionalDef()) : false;
+    bool isOptDef = IIOpNum < TID.getNumOperands() &&
+      TID.OpInfo[IIOpNum].isOptionalDef();
     MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef));
     
     // Verify that it is right.
@@ -681,8 +711,7 @@
     unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getValue();
 
     // Create the extract_subreg machine instruction.
-    MachineInstr *MI =
-      new MachineInstr(BB, TII->get(TargetInstrInfo::EXTRACT_SUBREG));
+    MachineInstr *MI = BuildMI(TII->get(TargetInstrInfo::EXTRACT_SUBREG));
 
     // Figure out the register class to create for the destreg.
     unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
@@ -704,7 +733,7 @@
     MI->addOperand(MachineOperand::CreateReg(VRBase, true));
     AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
     MI->addOperand(MachineOperand::CreateImm(SubIdx));
-    
+    BB->push_back(MI);    
   } else if (Opc == TargetInstrInfo::INSERT_SUBREG ||
              Opc == TargetInstrInfo::SUBREG_TO_REG) {
     SDOperand N0 = Node->getOperand(0);
@@ -726,8 +755,7 @@
     }
     
     // Create the insert_subreg or subreg_to_reg machine instruction.
-    MachineInstr *MI =
-      new MachineInstr(BB, TII->get(Opc));
+    MachineInstr *MI = BuildMI(TII->get(Opc));
     MI->addOperand(MachineOperand::CreateReg(VRBase, true));
     
     // If creating a subreg_to_reg, then the first input operand
@@ -740,6 +768,7 @@
     // Add the subregster being inserted
     AddOperand(MI, N1, 0, 0, VRBaseMap);
     MI->addOperand(MachineOperand::CreateImm(SubIdx));
+    BB->push_back(MI);
   } else
     assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg");
      
@@ -762,9 +791,12 @@
       EmitSubregNode(Node, VRBaseMap);
       return;
     }
+
+    if (Opc == TargetInstrInfo::IMPLICIT_DEF)
+      // We want a unique VR for each IMPLICIT_DEF use.
+      return;
     
     const TargetInstrDesc &II = TII->get(Opc);
-
     unsigned NumResults = CountResults(Node);
     unsigned NodeOperands = CountOperands(Node);
     unsigned MemOperandsEnd = ComputeMemOperandsEnd(Node);
@@ -778,7 +810,7 @@
 #endif
 
     // Create the new machine instruction.
-    MachineInstr *MI = new MachineInstr(II);
+    MachineInstr *MI = BuildMI(II);
     
     // Add result register values for things that are defined by this
     // instruction.
@@ -812,7 +844,7 @@
     if (II.usesCustomDAGSchedInsertionHook())
       // Insert this instruction into the basic block using a target
       // specific inserter which may returns a new basic block.
-      BB = DAG.getTargetLoweringInfo().EmitInstrWithCustomInserter(MI, BB);
+      BB = TLI->EmitInstrWithCustomInserter(MI, BB);
     else
       BB->push_back(MI);
 
@@ -875,8 +907,7 @@
         --NumOps;  // Ignore the flag operand.
       
       // Create the inline asm machine instruction.
-      MachineInstr *MI =
-        new MachineInstr(BB, TII->get(TargetInstrInfo::INLINEASM));
+      MachineInstr *MI = BuildMI(TII->get(TargetInstrInfo::INLINEASM));
 
       // Add the asm string as an external symbol operand.
       const char *AsmStr =
@@ -929,6 +960,7 @@
           break;
         }
       }
+      BB->push_back(MI);
       break;
     }
     }
@@ -1070,17 +1102,18 @@
   DenseMap<SDOperand, unsigned> VRBaseMap;
   DenseMap<SUnit*, unsigned> CopyVRBaseMap;
   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)
-        EmitNode(SU->FlaggedNodes[j], SU->InstanceNo, VRBaseMap);
-      if (SU->Node)
-        EmitNode(SU->Node, SU->InstanceNo, VRBaseMap);
-      else
-        EmitCrossRCCopy(SU, CopyVRBaseMap);
-    } else {
+    SUnit *SU = Sequence[i];
+    if (!SU) {
       // Null SUnit* is a noop.
       EmitNoop();
+      continue;
     }
+    for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; ++j)
+      EmitNode(SU->FlaggedNodes[j], SU->InstanceNo, VRBaseMap);
+    if (!SU->Node)
+      EmitCrossRCCopy(SU, CopyVRBaseMap);
+    else
+      EmitNode(SU->Node, SU->InstanceNo, VRBaseMap);
   }
 
   if (isEntryBB && SchedLiveInCopies)





More information about the llvm-commits mailing list