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

Chris Lattner lattner at cs.uiuc.edu
Mon Aug 29 16:21:40 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

ScheduleDAG.cpp updated: 1.17 -> 1.18
---
Log message:

Add a hack to avoid some horrible code in some cases by always emitting
token chains first.  For this C function:

int test() {
  int i;
  for (i = 0; i < 100000; ++i)
    foo();
}

Instead of emitting this (condition before call)

.LBB_test_1:    ; no_exit
        addi r30, r30, 1
        lis r2, 1
        ori r2, r2, 34464
        cmpw cr2, r30, r2
        bl L_foo$stub
        bne cr2, .LBB_test_1    ; no_exit

Emit this:

.LBB_test_1:    ; no_exit
        bl L_foo$stub
        addi r30, r30, 1
        lis r2, 1
        ori r2, r2, 34464
        cmpw cr0, r30, r2
        bne cr0, .LBB_test_1    ; no_exit

Which makes it so we don't have to save/restore cr2 in the prolog/epilog of
the function.

This also makes the code much more similar to what the pattern isel produces.



---
Diffs of the changes:  (+31 -12)

 ScheduleDAG.cpp |   43 +++++++++++++++++++++++++++++++------------
 1 files changed, 31 insertions(+), 12 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.17 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.18
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.17	Fri Aug 26 19:58:02 2005
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp	Mon Aug 29 18:21:29 2005
@@ -97,6 +97,7 @@
     while (NodeOperands &&
            Op.getOperand(NodeOperands-1).getValueType() == MVT::Flag)
       --NodeOperands;
+    
     if (NodeOperands &&    // Ignore chain if it exists.
         Op.getOperand(NodeOperands-1).getValueType() == MVT::Other)
       --NodeOperands;
@@ -125,18 +126,24 @@
       }
     }
     
-    // Emit all of the operands of this instruction, adding them to the
+    // If there is a token chain operand, emit it first, as a hack to get avoid
+    // really bad cases.
+    if (Op.getNumOperands() > NodeOperands &&
+        Op.getOperand(NodeOperands).getValueType() == MVT::Other)
+      Emit(Op.getOperand(NodeOperands));
+    
+    // Emit all of the actual operands of this instruction, adding them to the
     // instruction as appropriate.
-    for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
+    for (unsigned i = 0; i != NodeOperands; ++i) {
       if (Op.getOperand(i).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
         // simpler here.
-        unsigned R = Emit(Op.getOperand(i));
-        // Add an operand, unless this corresponds to a chain or flag node.
-        MVT::ValueType VT = Op.getOperand(i).getValueType();
-        if (VT != MVT::Other && VT != MVT::Flag)
-          MI->addRegOperand(R, MachineOperand::Use);
+        assert(Op.getOperand(i).getValueType() != MVT::Other &&
+               Op.getOperand(i).getValueType() != MVT::Flag &&
+               "Chain and flag operands should occur at end of operand list!");
+        
+        MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use);
       } else if (ConstantSDNode *C =
                                    dyn_cast<ConstantSDNode>(Op.getOperand(i))) {
         MI->addZeroExtImm64Operand(C->getValue());
@@ -159,14 +166,26 @@
                  dyn_cast<ExternalSymbolSDNode>(Op.getOperand(i))) {
         MI->addExternalSymbolOperand(ES->getSymbol(), false);
       } else {
-        unsigned R = Emit(Op.getOperand(i));
-        // Add an operand, unless this corresponds to a chain or flag node.
-        MVT::ValueType VT = Op.getOperand(i).getValueType();
-        if (VT != MVT::Other && VT != MVT::Flag)
-          MI->addRegOperand(R, MachineOperand::Use);
+        assert(Op.getOperand(i).getValueType() != MVT::Other &&
+               Op.getOperand(i).getValueType() != MVT::Flag &&
+               "Chain and flag operands should occur at end of operand list!");
+        MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use);
       }
     }
 
+    // Finally, if this node has any flag operands, we *must* emit them last, to
+    // avoid emitting operations that might clobber the flags.
+    if (Op.getNumOperands() > NodeOperands) {
+      unsigned i = NodeOperands;
+      if (Op.getOperand(i).getValueType() == MVT::Other)
+        ++i;  // the chain is already selected.
+      for (; i != Op.getNumOperands(); ++i) {
+        assert(Op.getOperand(i).getValueType() == MVT::Flag &&
+               "Must be flag operands!");
+        Emit(Op.getOperand(i));
+      }
+    }
+    
     // Now that we have emitted all operands, emit this instruction itself.
     if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) {
       BB->insert(BB->end(), MI);






More information about the llvm-commits mailing list