[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Aug 18 13:08:10 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

ScheduleDAG.cpp updated: 1.1 -> 1.2
---
Log message:

Implement the first chunk of a code emitter.  This is sophisticated enough to
codegen:

_empty:
.LBB_empty_0:   ; 
        blr

but can't do anything more (yet). :)



---
Diffs of the changes:  (+94 -1)

 ScheduleDAG.cpp |   95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 94 insertions(+), 1 deletion(-)


Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.1 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.2
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.1	Thu Aug 18 13:45:24 2005
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp	Thu Aug 18 15:07:59 2005
@@ -14,10 +14,103 @@
 
 #define DEBUG_TYPE "sched"
 #include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetInstrInfo.h"
 using namespace llvm;
 
+namespace {
+  class SimpleSched {
+    SelectionDAG &DAG;
+    MachineBasicBlock *BB;
+    const TargetMachine &TM;
+    const TargetInstrInfo &TII;
+    
+    std::map<SDNode *, unsigned> EmittedOps;
+  public:
+    SimpleSched(SelectionDAG &D, MachineBasicBlock *bb)
+      : DAG(D), BB(bb), TM(D.getTarget()), TII(*TM.getInstrInfo()) {
+      assert(&TII && "Target doesn't provide instr info?");
+    }
+    
+    void Run() {
+      Emit(DAG.getRoot());
+    }
+    
+  private:
+    unsigned Emit(SDOperand Op);
+  };
+}
+
+unsigned SimpleSched::Emit(SDOperand Op) {
+  // Check to see if we have already emitted this.  If so, return the value
+  // already emitted.  Note that if a node has a single use it cannot be
+  // revisited, so don't bother putting it in the map.
+  unsigned *OpSlot;
+  if (Op.Val->hasOneUse()) {
+    OpSlot = 0;  // No reuse possible.
+  } else {
+    std::map<SDNode *, unsigned>::iterator OpI = EmittedOps.lower_bound(Op.Val);
+    if (OpI != EmittedOps.end() && OpI->first == Op.Val)
+      return OpI->second + Op.ResNo;
+    OpSlot = &EmittedOps.insert(OpI, std::make_pair(Op.Val, 0))->second;
+  }
+  
+  unsigned ResultReg = 0;
+  if (Op.isTargetOpcode()) {
+    unsigned Opc = Op.getTargetOpcode();
+    const TargetInstrDescriptor &II = TII.get(Opc);
+
+    // Target nodes have any register or immediate operands before any chain
+    // nodes.  Check that the DAG matches the TD files's expectation of #
+    // operands.
+    assert((unsigned(II.numOperands) == Op.getNumOperands() ||
+            // It could be some number of operands followed by a token chain.
+           (unsigned(II.numOperands)+1 == Op.getNumOperands() &&
+            Op.getOperand(II.numOperands).getValueType() == MVT::Other)) &&
+           "#operands for dag node doesn't match .td file!"); 
+
+    // Create the new machine instruction.
+    MachineInstr *MI = new MachineInstr(Opc, II.numOperands, true, true);
+    
+    // Add result register values for things that are defined by this
+    // instruction.
+    assert(Op.Val->getNumValues() == 1 &&
+           Op.getValue(0).getValueType() == MVT::Other &&
+           "Return values not implemented yet");
+    
+    // Emit all of the operands of this instruction, adding them to the
+    // instruction as appropriate.
+    for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
+      if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(i))) {
+        MI->addZeroExtImm64Operand(C->getValue());
+      } else if (RegisterSDNode*R =dyn_cast<RegisterSDNode>(Op.getOperand(i))) {
+        MI->addRegOperand(R->getReg(), MachineOperand::Use);
+      } else {
+        unsigned R = Emit(Op.getOperand(i));
+        // Add an operand, unless this corresponds to a chain node.
+        if (Op.getOperand(i).getValueType() != MVT::Other)
+          MI->addRegOperand(R, MachineOperand::Use);
+      }
+    }
+
+    // Now that we have emitted all operands, emit this instruction itself.
+    BB->insert(BB->end(), MI);
+  } else {
+    switch (Op.getOpcode()) {
+    default: assert(0 &&
+                    "This target-independent node should have been selected!");
+    case ISD::EntryToken: break;
+    }
+  }
+  
+  if (OpSlot) *OpSlot = ResultReg;
+  return ResultReg+Op.ResNo;
+}
+
+
 /// Pick a safe ordering and emit instructions for each target node in the
 /// graph.
 void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &SD) {
-  
+  SimpleSched(SD, BB).Run();  
 }






More information about the llvm-commits mailing list