[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Oct 6 11:46:03 PDT 2005



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelDAGToDAG.cpp updated: 1.93 -> 1.94
---
Log message:

Add a recursive-iterative hybrid stage to attempt to reduce stack space, this
helps but not enough.

Start pulling cases out of PPC32DAGToDAGISel::Select.  With GCC 4, this function
required 8512 bytes of stack space for each invocation (GCC 3 required less
than 700 bytes).  Pulling this first function out gets us down to 8224.  More
to come :(



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

 PPC32ISelDAGToDAG.cpp |  139 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 94 insertions(+), 45 deletions(-)


Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.93 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.94
--- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.93	Sun Oct  2 02:07:49 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp	Thu Oct  6 13:45:51 2005
@@ -83,26 +83,70 @@
     
     /// InstructionSelectBasicBlock - This callback is invoked by
     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-    virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
-      DEBUG(BB->dump());
-      // Select target instructions for the DAG.
-      DAG.setRoot(Select(DAG.getRoot()));
-      CodeGenMap.clear();
-      DAG.RemoveDeadNodes();
-      
-      // Emit machine code to BB. 
-      ScheduleAndEmitDAG(DAG);
-    }
- 
+    virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
+    
     virtual const char *getPassName() const {
       return "PowerPC DAG->DAG Pattern Instruction Selection";
     } 
 
 // Include the pieces autogenerated from the target description.
 #include "PPC32GenDAGISel.inc"
+    
+private:
+    SDOperand SelectDYNAMIC_STACKALLOC(SDOperand N);
   };
 }
 
+/// InstructionSelectBasicBlock - This callback is invoked by
+/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
+void PPC32DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
+  DEBUG(BB->dump());
+  
+  // The selection process is inherently a bottom-up recursive process (users
+  // select their uses before themselves).  Given infinite stack space, we
+  // could just start selecting on the root and traverse the whole graph.  In
+  // practice however, this causes us to run out of stack space on large basic
+  // blocks.  To avoid this problem, select the entry node, then all its uses,
+  // iteratively instead of recursively.
+  std::vector<SDOperand> Worklist;
+  Worklist.push_back(DAG.getEntryNode());
+  
+  // Note that we can do this in the PPC target (scanning forward across token
+  // chain edges) because no nodes ever get folded across these edges.  On a
+  // target like X86 which supports load/modify/store operations, this would
+  // have to be more careful.
+  while (!Worklist.empty()) {
+    SDOperand Node = Worklist.back();
+    Worklist.pop_back();
+    
+    if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
+         Node.Val->getOpcode() < PPCISD::FIRST_NUMBER) ||
+        CodeGenMap.count(Node)) continue;
+    
+    for (SDNode::use_iterator UI = Node.Val->use_begin(),
+         E = Node.Val->use_end(); UI != E; ++UI) {
+      // Scan the values.  If this use has a value that is a token chain, add it
+      // to the worklist.
+      SDNode *User = *UI;
+      for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
+        if (User->getValueType(i) == MVT::Other) {
+          Worklist.push_back(SDOperand(User, i));
+          break; 
+        }
+    }
+
+    // Finally, legalize this node.
+    Select(Node);
+  }
+  
+  // Select target instructions for the DAG.
+  DAG.setRoot(Select(DAG.getRoot()));
+  CodeGenMap.clear();
+  DAG.RemoveDeadNodes();
+  
+  // Emit machine code to BB. 
+  ScheduleAndEmitDAG(DAG);
+}
 
 /// getGlobalBaseReg - Output the instructions required to put the
 /// base address to use for accessing globals into a register.
@@ -632,6 +676,43 @@
   }
 }
 
+SDOperand PPC32DAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) {
+  SDNode *N = Op.Val;
+
+  // FIXME: We are currently ignoring the requested alignment for handling
+  // greater than the stack alignment.  This will need to be revisited at some
+  // point.  Align = N.getOperand(2);
+  if (!isa<ConstantSDNode>(N->getOperand(2)) ||
+      cast<ConstantSDNode>(N->getOperand(2))->getValue() != 0) {
+    std::cerr << "Cannot allocate stack object with greater alignment than"
+    << " the stack alignment yet!";
+    abort();
+  }
+  SDOperand Chain = Select(N->getOperand(0));
+  SDOperand Amt   = Select(N->getOperand(1));
+  
+  SDOperand R1Reg = CurDAG->getRegister(PPC::R1, MVT::i32);
+  
+  SDOperand R1Val = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32);
+  Chain = R1Val.getValue(1);
+  
+  // Subtract the amount (guaranteed to be a multiple of the stack alignment)
+  // from the stack pointer, giving us the result pointer.
+  SDOperand Result = CurDAG->getTargetNode(PPC::SUBF, MVT::i32, Amt, R1Val);
+  
+  // Copy this result back into R1.
+  Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R1Reg, Result);
+  
+  // Copy this result back out of R1 to make sure we're not using the stack
+  // space without decrementing the stack pointer.
+  Result = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32);
+  
+  // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg.
+  CodeGenMap[Op.getValue(0)] = Result;
+  CodeGenMap[Op.getValue(1)] = Result.getValue(1);
+  return SDOperand(Result.Val, Op.ResNo);
+}
+
 // Select - Convert the specified operand from a target-independent to a
 // target-specific node if it hasn't already been changed.
 SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
@@ -718,40 +799,8 @@
       CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA);
     return SDOperand(N, 0);
   }
-  case ISD::DYNAMIC_STACKALLOC: {
-    // FIXME: We are currently ignoring the requested alignment for handling
-    // greater than the stack alignment.  This will need to be revisited at some
-    // point.  Align = N.getOperand(2);
-    if (!isa<ConstantSDNode>(N->getOperand(2)) ||
-        cast<ConstantSDNode>(N->getOperand(2))->getValue() != 0) {
-      std::cerr << "Cannot allocate stack object with greater alignment than"
-                << " the stack alignment yet!";
-      abort();
-    }
-    SDOperand Chain = Select(N->getOperand(0));
-    SDOperand Amt   = Select(N->getOperand(1));
-    
-    SDOperand R1Reg = CurDAG->getRegister(PPC::R1, MVT::i32);
-    
-    SDOperand R1Val = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32);
-    Chain = R1Val.getValue(1);
-    
-    // Subtract the amount (guaranteed to be a multiple of the stack alignment)
-    // from the stack pointer, giving us the result pointer.
-    SDOperand Result = CurDAG->getTargetNode(PPC::SUBF, MVT::i32, Amt, R1Val);
-
-    // Copy this result back into R1.
-    Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R1Reg, Result);
-    
-    // Copy this result back out of R1 to make sure we're not using the stack
-    // space without decrementing the stack pointer.
-    Result = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32);
-    
-    // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg.
-    CodeGenMap[Op.getValue(0)] = Result;
-    CodeGenMap[Op.getValue(1)] = Result.getValue(1);
-    return SDOperand(Result.Val, Op.ResNo);
-  }      
+  case ISD::DYNAMIC_STACKALLOC:
+    return SelectDYNAMIC_STACKALLOC(Op);
   case PPCISD::FSEL: {
     SDOperand Comparison = Select(N->getOperand(0));
     // Extend the comparison to 64-bits.






More information about the llvm-commits mailing list