diff options
author | Duncan Sands <baldrick@free.fr> | 2008-02-27 13:34:40 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-02-27 13:34:40 +0000 |
commit | 077f9b20d0e8659d00a09046a63e28edf0665ffe (patch) | |
tree | 19536af56a9bc4a2f026f4b006c016d51fbff242 /lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | |
parent | 0a4c3782c8d558a9859a90ae8e2d5d0efa057e41 (diff) |
LegalizeTypes support for EXTRACT_VECTOR_ELT. The
approach taken is different to that in LegalizeDAG
when it is a question of expanding or promoting the
result type: for example, if extracting an i64 from
a <2 x i64>, when i64 needs expanding, it bitcasts
the vector to <4 x i32>, extracts the appropriate
two i32's, and uses those for the Lo and Hi parts.
Likewise, when extracting an i16 from a <4 x i16>,
and i16 needs promoting, it bitcasts the vector to
<2 x i32>, extracts the appropriate i32, twiddles
the bits if necessary, and uses that as the promoted
value. This puts more pressure on bitcast legalization,
and I've added the appropriate cases. They needed to
be added anyway since users can generate such bitcasts
too if they want to. Also, when considering various
cases (Legal, Promote, Expand, Scalarize, Split) it is
a pain that expand can correspond to Expand, Scalarize
or Split, so I've changed the LegalizeTypes enum so it
lists those different cases - now Expand only means
splitting a scalar in two.
The code produced is the same as by LegalizeDAG for
all relevant testcases, except for
2007-10-31-extractelement-i64.ll, where the code seems
to have improved (see below; can an expert please tell
me if it is better or not).
Before < vs after >.
< subl $92, %esp
< movaps %xmm0, 64(%esp)
< movaps %xmm0, (%esp)
< movl 4(%esp), %eax
< movl %eax, 28(%esp)
< movl (%esp), %eax
< movl %eax, 24(%esp)
< movq 24(%esp), %mm0
< movq %mm0, 56(%esp)
---
> subl $44, %esp
> movaps %xmm0, 16(%esp)
> pshufd $1, %xmm0, %xmm1
> movd %xmm1, 4(%esp)
> movd %xmm0, (%esp)
> movq (%esp), %mm0
> movq %mm0, 8(%esp)
< subl $92, %esp
< movaps %xmm0, 64(%esp)
< movaps %xmm0, (%esp)
< movl 12(%esp), %eax
< movl %eax, 28(%esp)
< movl 8(%esp), %eax
< movl %eax, 24(%esp)
< movq 24(%esp), %mm0
< movq %mm0, 56(%esp)
---
> subl $44, %esp
> movaps %xmm0, 16(%esp)
> pshufd $3, %xmm0, %xmm1
> movd %xmm1, 4(%esp)
> movhlps %xmm0, %xmm0
> movd %xmm0, (%esp)
> movq (%esp), %mm0
> movq %mm0, 8(%esp)
< subl $92, %esp
< movaps %xmm0, 64(%esp)
---
> subl $44, %esp
< movl 16(%esp), %eax
< movl %eax, 48(%esp)
< movl 20(%esp), %eax
< movl %eax, 52(%esp)
< movaps %xmm0, (%esp)
< movl 4(%esp), %eax
< movl %eax, 60(%esp)
< movl (%esp), %eax
< movl %eax, 56(%esp)
---
> pshufd $1, %xmm0, %xmm1
> movd %xmm1, 4(%esp)
> movd %xmm0, (%esp)
> movd %xmm1, 12(%esp)
> movd %xmm0, 8(%esp)
< subl $92, %esp
< movaps %xmm0, 64(%esp)
---
> subl $44, %esp
< movl 24(%esp), %eax
< movl %eax, 48(%esp)
< movl 28(%esp), %eax
< movl %eax, 52(%esp)
< movaps %xmm0, (%esp)
< movl 12(%esp), %eax
< movl %eax, 60(%esp)
< movl 8(%esp), %eax
< movl %eax, 56(%esp)
---
> pshufd $3, %xmm0, %xmm1
> movd %xmm1, 4(%esp)
> movhlps %xmm0, %xmm0
> movd %xmm0, (%esp)
> movd %xmm1, 12(%esp)
> movd %xmm0, 8(%esp)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47672 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeTypes.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index cfaf0a9c93..43acb5ba31 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -68,25 +68,26 @@ void DAGTypeLegalizer::run() { unsigned NumResults = N->getNumValues(); do { MVT::ValueType ResultVT = N->getValueType(i); - LegalizeAction Action = getTypeAction(ResultVT); - if (Action == Promote) { + switch (getTypeAction(ResultVT)) { + default: + assert(false && "Unknown action!"); + case Legal: + break; + case Promote: PromoteResult(N, i); goto NodeDone; - } else if (Action == Expand) { - // Expand can mean 1) split integer in half 2) scalarize single-element - // vector 3) split vector in half. - if (!MVT::isVector(ResultVT)) - ExpandResult(N, i); - else if (MVT::getVectorNumElements(ResultVT) == 1) - ScalarizeResult(N, i); // Scalarize the single-element vector. - else - SplitResult(N, i); // Split the vector in half. + case Expand: + ExpandResult(N, i); + goto NodeDone; + case Scalarize: + ScalarizeResult(N, i); + goto NodeDone; + case Split: + SplitResult(N, i); goto NodeDone; - } else { - assert(Action == Legal && "Unknown action!"); } } while (++i < NumResults); - + // Scan the operand list for the node, handling any nodes with operands that // are illegal. { @@ -94,25 +95,25 @@ void DAGTypeLegalizer::run() { bool NeedsRevisit = false; for (i = 0; i != NumOperands; ++i) { MVT::ValueType OpVT = N->getOperand(i).getValueType(); - LegalizeAction Action = getTypeAction(OpVT); - if (Action == Promote) { + switch (getTypeAction(OpVT)) { + default: + assert(false && "Unknown action!"); + case Legal: + continue; + case Promote: NeedsRevisit = PromoteOperand(N, i); break; - } else if (Action == Expand) { - // Expand can mean 1) split integer in half 2) scalarize single-element - // vector 3) split vector in half. - if (!MVT::isVector(OpVT)) { - NeedsRevisit = ExpandOperand(N, i); - } else if (MVT::getVectorNumElements(OpVT) == 1) { - // Scalarize the single-element vector. - NeedsRevisit = ScalarizeOperand(N, i); - } else { - NeedsRevisit = SplitOperand(N, i); // Split the vector in half. - } + case Expand: + NeedsRevisit = ExpandOperand(N, i); + break; + case Scalarize: + NeedsRevisit = ScalarizeOperand(N, i); + break; + case Split: + NeedsRevisit = SplitOperand(N, i); break; - } else { - assert(Action == Legal && "Unknown action!"); } + break; } // If the node needs revisiting, don't add all users to the worklist etc. @@ -432,7 +433,7 @@ SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) { case Legal: break; case Promote: Op2 = GetPromotedOp(Op2); break; } - + // The length could have any action required. SDOperand Length = N->getOperand(3); switch (getTypeAction(Length.getValueType())) { @@ -444,21 +445,21 @@ SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) { GetExpandedOp(Length, Length, Dummy); break; } - + SDOperand Align = N->getOperand(4); switch (getTypeAction(Align.getValueType())) { default: assert(0 && "Unknown action for memop operand"); case Legal: break; case Promote: Align = GetPromotedZExtOp(Align); break; } - + SDOperand AlwaysInline = N->getOperand(5); switch (getTypeAction(AlwaysInline.getValueType())) { default: assert(0 && "Unknown action for memop operand"); case Legal: break; case Promote: AlwaysInline = GetPromotedZExtOp(AlwaysInline); break; } - + SDOperand Ops[] = { Chain, Ptr, Op2, Length, Align, AlwaysInline }; return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6); } |