diff options
author | Chris Lattner <sabre@nondot.org> | 2005-08-16 21:55:35 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-08-16 21:55:35 +0000 |
commit | d5d0f9bd20d9df07d6b4d41b7e8ed6d33b6a649d (patch) | |
tree | 411d221bc8fb4a0221daeac5a4e5574c43b13078 /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
parent | 7cbd525ba85ebe440d15fa359ec940e404d14906 (diff) |
Eliminate the RegSDNode class, which 3 nodes (CopyFromReg/CopyToReg/ImplicitDef)
used to tack a register number onto the node.
Instead of doing this, make a new node, RegisterSDNode, which is a leaf
containing a register number. These three operations just become normal
DAG nodes now, instead of requiring special handling.
Note that with this change, it is no longer correct to make illegal
CopyFromReg/CopyToReg nodes. The legalizer will not touch them, and this
is bad, so don't do it. :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22806 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 512a62deff..44553afa3c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -296,7 +296,27 @@ public: FuncInfo.ValueMap.find(V); assert(VMI != FuncInfo.ValueMap.end() && "Value not in map!"); - return N = DAG.getCopyFromReg(VMI->second, VT, DAG.getEntryNode()); + unsigned InReg = VMI->second; + + // If this type is not legal, make it so now. + MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT); + + N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT); + if (DestVT < VT) { + // Source must be expanded. This input value is actually coming from the + // register pair VMI->second and VMI->second+1. + N = DAG.getNode(ISD::BUILD_PAIR, VT, N, + DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT)); + } else { + if (DestVT > VT) { // Promotion case + if (MVT::isFloatingPoint(VT)) + N = DAG.getNode(ISD::FP_ROUND, VT, N); + else + N = DAG.getNode(ISD::TRUNCATE, VT, N); + } + } + + return N; } const SDOperand &setValue(const Value *V, SDOperand NewN) { @@ -957,12 +977,31 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) { SDOperand SelectionDAGISel:: CopyValueToVirtualRegister(SelectionDAGLowering &SDL, Value *V, unsigned Reg) { - SelectionDAG &DAG = SDL.DAG; SDOperand Op = SDL.getValue(V); assert((Op.getOpcode() != ISD::CopyFromReg || - cast<RegSDNode>(Op)->getReg() != Reg) && + cast<RegisterSDNode>(Op.getOperand(1))->getReg() != Reg) && "Copy from a reg to the same reg!"); - return DAG.getCopyToReg(SDL.getRoot(), Op, Reg); + + // If this type is not legal, we must make sure to not create an invalid + // register use. + MVT::ValueType SrcVT = Op.getValueType(); + MVT::ValueType DestVT = TLI.getTypeToTransformTo(SrcVT); + SelectionDAG &DAG = SDL.DAG; + if (SrcVT == DestVT) { + return DAG.getCopyToReg(SDL.getRoot(), Reg, Op); + } else if (SrcVT < DestVT) { + // The src value is promoted to the register. + Op = DAG.getNode(ISD::ZERO_EXTEND, DestVT, Op); + return DAG.getCopyToReg(SDL.getRoot(), Reg, Op); + } else { + // The src value is expanded into multiple registers. + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT, + Op, DAG.getConstant(0, MVT::i32)); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT, + Op, DAG.getConstant(1, MVT::i32)); + Op = DAG.getCopyToReg(SDL.getRoot(), Reg, Lo); + return DAG.getCopyToReg(Op, Reg+1, Hi); + } } /// IsOnlyUsedInOneBasicBlock - If the specified argument is only used in a |