| Index: src/IceTargetLowering.h
|
| diff --git a/src/IceTargetLowering.h b/src/IceTargetLowering.h
|
| index 3477f709b2ef0ff60a6693d8625a88e125eb7eca..c8c9eb0da56e784c1b5734d24c727c05fd08110f 100644
|
| --- a/src/IceTargetLowering.h
|
| +++ b/src/IceTargetLowering.h
|
| @@ -325,6 +325,10 @@ private:
|
| // locking/unlocking) to prevent nested bundles.
|
| bool AutoBundling = false;
|
|
|
| + /// This indicates whether we are in the genTargetHelperCalls phase, and
|
| + /// therefore can do things like scalarization.
|
| + bool GeneratingTargetHelpers = false;
|
| +
|
| // _bundle_lock(), and _bundle_unlock(), were made private to force subtargets
|
| // to use the AutoBundle helper.
|
| void
|
| @@ -469,73 +473,39 @@ protected:
|
|
|
| /// Generalizes scalarizeArithmetic to support other instruction types.
|
| ///
|
| - /// MakeInstruction is a function-like object with signature
|
| + /// insertScalarInstruction 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) {
|
| + template <typename... Operands,
|
| + typename F = std::function<Inst *(Variable *, Operands *...)>>
|
| + void scalarizeInstruction(Variable *Dest, F insertScalarInstruction,
|
| + Operands *... Srcs) {
|
| + assert(GeneratingTargetHelpers &&
|
| + "scalarizeInstruction called during incorrect phase");
|
| const Type DestTy = Dest->getType();
|
| assert(isVectorType(DestTy));
|
| 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 operation as a scalar operation.
|
| - 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) {
|
| - const Type DestTy = Dest->getType();
|
| - assert(isVectorType(DestTy));
|
| - 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);
|
| + auto *Index = Ctx->getConstantInt32(I);
|
| +
|
| + auto MakeExtract = [this, Index, NumElements](Operand *Src) {
|
| + assert(typeNumElements(Src->getType()) == NumElements);
|
|
|
| - // Extract the next two inputs.
|
| - Variable *Op0 = Func->makeVariable(Src0ElementTy);
|
| - Context.insert<InstExtractElement>(Op0, Src0, Index);
|
| + const auto ElementTy = typeElementType(Src->getType());
|
| + auto *Op = Func->makeVariable(ElementTy);
|
| + Context.insert<InstExtractElement>(Op, Src, Index);
|
| + return Op;
|
| + };
|
|
|
| // Perform the operation 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.
|
| + auto *Res = Func->makeVariable(DestElementTy);
|
| + auto *Arith = insertScalarInstruction(Res, MakeExtract(Srcs)...);
|
| genTargetHelperCallFor(Arith);
|
|
|
| - // Insert the result into position.
|
| Variable *DestT = Func->makeVariable(DestTy);
|
| Context.insert<InstInsertElement>(DestT, T, Res, Index);
|
| T = DestT;
|
|
|