Chromium Code Reviews| Index: src/IceTargetLowering.h |
| diff --git a/src/IceTargetLowering.h b/src/IceTargetLowering.h |
| index 55597ca14e7d212c5ee38c3bbf68f8f97c9252f3..678dd3d87d1300610bac3dc0e17356de6939fa82 100644 |
| --- a/src/IceTargetLowering.h |
| +++ b/src/IceTargetLowering.h |
| @@ -467,6 +467,83 @@ protected: |
| void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, |
| Operand *Src0, Operand *Src1); |
| + /// Generalizes scalarizeArithmetic to support other instruction types. |
| + /// |
| + /// MakeInstruction is a function-like object with signature |
| + /// (Variable *Dest, Variable *Src0, Variable *Src1) -> Instr *. |
| + template<typename F> |
| + void scalarizeInstruction(Variable *Dest, Operand *Src0, Operand *Src1, |
| + F &&MakeInstruction) { |
| + assert(isVectorType(Dest->getType())); |
|
Jim Stichnoth
2016/02/10 19:08:11
I would "assert(isVectorType(DestTy));" and move i
Eric Holk
2016/02/10 21:07:20
Done.
|
| + const Type DestTy = Dest->getType(); |
| + const Type DestElementTy = typeElementType(DestTy); |
| + const SizeT NumElements = typeNumElements(DestTy); |
| + const Type Src0ElementTy = typeElementType(Src0->getType()); |
| + const Type Src1ElementTy = typeElementType(Src1->getType()); |
| + |
| + assert(NumElements == typeNumElements(Src0->getType())); |
| + assert(NumElements == typeNumElements(Src1->getType())); |
| + |
| + Variable *T = Func->makeVariable(DestTy); |
| + Context.insert<InstFakeDef>(T); |
| + for (SizeT I = 0; I < NumElements; ++I) { |
| + Constant *Index = Ctx->getConstantInt32(I); |
| + |
| + // Extract the next two inputs. |
| + Variable *Op0 = Func->makeVariable(Src0ElementTy); |
| + Context.insert<InstExtractElement>(Op0, Src0, Index); |
| + Variable *Op1 = Func->makeVariable(Src1ElementTy); |
| + Context.insert<InstExtractElement>(Op1, Src1, Index); |
| + |
| + // Perform the arithmetic as a scalar operation. |
|
Jim Stichnoth
2016/02/10 19:08:12
You probably want change "arithmetic" to be more g
Eric Holk
2016/02/10 21:07:20
Done.
|
| + Variable *Res = Func->makeVariable(DestElementTy); |
| + auto Arith = MakeInstruction(Res, Op0, Op1); |
| + // We might have created an operation that needed a helper call. |
| + genTargetHelperCallFor(Arith); |
| + |
| + // Insert the result into position. |
| + Variable *DestT = Func->makeVariable(DestTy); |
| + Context.insert<InstInsertElement>(DestT, T, Res, Index); |
| + T = DestT; |
| + } |
| + Context.insert<InstAssign>(Dest, T); |
| + } |
| + |
| + template<typename F> |
| + void scalarizeUnaryInstruction(Variable *Dest, Operand *Src0, |
| + F &&MakeInstruction) { |
| + assert(isVectorType(Dest->getType())); |
| + const Type DestTy = Dest->getType(); |
| + const Type DestElementTy = typeElementType(DestTy); |
| + const SizeT NumElements = typeNumElements(DestTy); |
| + const Type Src0ElementTy = typeElementType(Src0->getType()); |
| + |
| + assert(NumElements == typeNumElements(Src0->getType())); |
| + |
| + Variable *T = Func->makeVariable(DestTy); |
| + Context.insert<InstFakeDef>(T); |
| + for (SizeT I = 0; I < NumElements; ++I) { |
| + Constant *Index = Ctx->getConstantInt32(I); |
| + |
| + // Extract the next two inputs. |
| + Variable *Op0 = Func->makeVariable(Src0ElementTy); |
| + Context.insert<InstExtractElement>(Op0, Src0, Index); |
| + |
| + // Perform the arithmetic as a scalar operation. |
| + Variable *Res = Func->makeVariable(DestElementTy); |
| + auto Arith = MakeInstruction(Res, Op0); |
| + // We might have created an operation that needed a helper call. |
| + genTargetHelperCallFor(Arith); |
| + |
| + // Insert the result into position. |
| + Variable *DestT = Func->makeVariable(DestTy); |
| + Context.insert<InstInsertElement>(DestT, T, Res, Index); |
| + T = DestT; |
| + } |
| + Context.insert<InstAssign>(Dest, T); |
| + } |
| + |
| + |
| /// SandboxType enumerates all possible sandboxing strategies that |
| enum SandboxType { |
| ST_None, |