[llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Wed Oct 19 17:29:13 PDT 2005



Changes in directory llvm/lib/Target/Alpha:

AlphaISelDAGToDAG.cpp added (r1.1)
---
Log message:

forgot this one

---
Diffs of the changes:  (+265 -0)

 AlphaISelDAGToDAG.cpp |  265 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 265 insertions(+)


Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
diff -c /dev/null llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.1
*** /dev/null	Wed Oct 19 19:29:12 2005
--- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp	Wed Oct 19 19:29:02 2005
***************
*** 0 ****
--- 1,265 ----
+ //===-- AlphaISelDAGToDAG.cpp - Alpha pattern matching inst selector ------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Andrew Lenharth and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines a pattern matching instruction selector for Alpha,
+ // converting from a legalized dag to a Alpha dag.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "Alpha.h"
+ #include "AlphaTargetMachine.h"
+ #include "AlphaISelLowering.h"
+ #include "llvm/CodeGen/MachineInstrBuilder.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/SSARegMap.h"
+ #include "llvm/CodeGen/SelectionDAG.h"
+ #include "llvm/CodeGen/SelectionDAGISel.h"
+ #include "llvm/Target/TargetOptions.h"
+ #include "llvm/ADT/Statistic.h"
+ #include "llvm/Constants.h"
+ #include "llvm/GlobalValue.h"
+ #include "llvm/Support/Debug.h"
+ #include "llvm/Support/MathExtras.h"
+ using namespace llvm;
+ 
+ namespace {
+ 
+   //===--------------------------------------------------------------------===//
+   /// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine
+   /// instructions for SelectionDAG operations.
+   ///
+   class AlphaDAGToDAGISel : public SelectionDAGISel {
+     AlphaTargetLowering AlphaLowering;
+ 
+   public:
+     AlphaDAGToDAGISel(TargetMachine &TM)
+       : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {}
+ 
+     /// getI64Imm - Return a target constant with the specified value, of type
+     /// i64.
+     inline SDOperand getI64Imm(unsigned Imm) {
+       return CurDAG->getTargetConstant(Imm, MVT::i64);
+     }
+ 
+     virtual bool runOnFunction(Function &Fn) {
+       return SelectionDAGISel::runOnFunction(Fn);
+     }
+    
+     // Select - Convert the specified operand from a target-independent to a
+     // target-specific node if it hasn't already been changed.
+     SDOperand Select(SDOperand Op);
+     
+     /// InstructionSelectBasicBlock - This callback is invoked by
+     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
+     virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
+     
+     virtual const char *getPassName() const {
+       return "Alpha DAG->DAG Pattern Instruction Selection";
+     } 
+ 
+ // Include the pieces autogenerated from the target description.
+ #include "AlphaGenDAGISel.inc"
+     
+ private:
+   };
+ }
+ 
+ /// InstructionSelectBasicBlock - This callback is invoked by
+ /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
+ void AlphaDAGToDAGISel::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 Alpha 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();
+     
+     // Chose from the least deep of the top two nodes.
+     if (!Worklist.empty() &&
+         Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth())
+       std::swap(Worklist.back(), Node);
+     
+     if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
+          Node.Val->getOpcode() < AlphaISD::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);
+ }
+ 
+ // Select - Convert the specified operand from a target-independent to a
+ // target-specific node if it hasn't already been changed.
+ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
+   SDNode *N = Op.Val;
+   if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
+       N->getOpcode() < AlphaISD::FIRST_NUMBER)
+     return Op;   // Already selected.
+ 
+   // If this has already been converted, use it.
+   std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
+   if (CGMI != CodeGenMap.end()) return CGMI->second;
+   
+   switch (N->getOpcode()) {
+   default: break;
+   case ISD::DYNAMIC_STACKALLOC:
+   case ISD::ADD_PARTS:
+   case ISD::SUB_PARTS:
+   case ISD::SETCC:
+   case ISD::CALL:
+   case ISD::TAILCALL:
+     assert(0 && "You want these too?");
+ 
+   case ISD::TokenFactor: {
+     SDOperand New;
+     if (N->getNumOperands() == 2) {
+       SDOperand Op0 = Select(N->getOperand(0));
+       SDOperand Op1 = Select(N->getOperand(1));
+       New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);
+     } else {
+       std::vector<SDOperand> Ops;
+       for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+         Ops.push_back(Select(N->getOperand(i)));
+       New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);
+     }
+     
+     CodeGenMap[Op] = New;
+     return New;
+   }
+   case ISD::CopyFromReg: {
+     SDOperand Chain = Select(N->getOperand(0));
+     if (Chain == N->getOperand(0)) return Op; // No change
+     SDOperand New = CurDAG->getCopyFromReg(Chain,
+          cast<RegisterSDNode>(N->getOperand(1))->getReg(), N->getValueType(0));
+     return New.getValue(Op.ResNo);
+   }
+   case ISD::CopyToReg: {
+     SDOperand Chain = Select(N->getOperand(0));
+     SDOperand Reg = N->getOperand(1);
+     SDOperand Val = Select(N->getOperand(2));
+     SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other,
+                                     Chain, Reg, Val);
+     CodeGenMap[Op] = New;
+     return New;
+   }
+   case ISD::UNDEF:
+     if (N->getValueType(0) == MVT::i64)
+       CurDAG->SelectNodeTo(N, Alpha::IDEF, MVT::i64);
+ //     else if (N->getValueType(0) == MVT::f32)
+ //       CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32);
+ //     else 
+ //       CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64);
+     return SDOperand(N, 0);
+   case ISD::FrameIndex: {
+ //     int FI = cast<FrameIndexSDNode>(N)->getIndex();
+ //     CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64,
+ //                          CurDAG->getTargetFrameIndex(FI, MVT::i32),
+ //                          getI32Imm(0));
+ //     return SDOperand(N, 0);
+     assert(0 && "Frame?, you are suppose to look through the window, not at the frame!");
+   }
+   case ISD::ConstantPool: {
+ //     Constant *C = cast<ConstantPoolSDNode>(N)->get();
+ //     SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i32);
+ //     if (PICEnabled)
+ //       Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI);
+ //     else
+ //       Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI);
+ //     CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI);
+ //     return SDOperand(N, 0);
+     assert(0 && "Constants are overrated");
+   }
+   case ISD::GlobalAddress: {
+ //     GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
+ //     SDOperand Tmp;
+ //     SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i32);
+ //     if (PICEnabled)
+ //       Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(), GA);
+ //     else
+ //       Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA);
+ 
+ //     if (GV->hasWeakLinkage() || GV->isExternal())
+ //       CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, GA, Tmp);
+ //     else
+ //       CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA);
+ //     return SDOperand(N, 0);
+     assert(0 && "GlobalAddresses are for wimps");
+   }
+ 
+   case ISD::CALLSEQ_START:
+   case ISD::CALLSEQ_END: {
+     unsigned Amt = cast<ConstantSDNode>(N->getOperand(1))->getValue();
+     unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
+                        Alpha::ADJUSTSTACKDOWN : Alpha::ADJUSTSTACKUP;
+     CurDAG->SelectNodeTo(N, Opc, MVT::Other,
+                          getI64Imm(Amt), Select(N->getOperand(0)));
+     return SDOperand(N, 0);
+   }
+   case ISD::RET: {
+     SDOperand Chain = Select(N->getOperand(0));     // Token chain.
+ 
+     if (N->getNumOperands() == 2) {
+       SDOperand Val = Select(N->getOperand(1));
+       if (N->getOperand(1).getValueType() == MVT::i64) {
+         Chain = CurDAG->getCopyToReg(Chain, Alpha::R0, Val);
+       }
+     }
+     //BuildMI(BB, Alpha::RET, 2, Alpha::R31).addReg(Alpha::R26).addImm(1);
+ 
+     // FIXME: add restoring of the RA to R26 to the chain
+     // Finally, select this to a ret instruction.
+     CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain);
+     return SDOperand(N, 0);
+   }
+ 
+ 
+ 
+   }
+   
+   return SelectCode(Op);
+ }
+ 
+ /// createAlphaISelDag - This pass converts a legalized DAG into a 
+ /// Alpha-specific DAG, ready for instruction scheduling.
+ ///
+ FunctionPass *llvm::createAlphaISelDag(TargetMachine &TM) {
+   return new AlphaDAGToDAGISel(TM);
+ }






More information about the llvm-commits mailing list