| Index: src/IceTargetLowering.h
|
| diff --git a/src/IceTargetLowering.h b/src/IceTargetLowering.h
|
| index 3477f709b2ef0ff60a6693d8625a88e125eb7eca..f5489dcef676696e79e96a8071dc935091e9931c 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
|
| @@ -467,41 +471,36 @@ protected:
|
| void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
|
| Operand *Src0, Operand *Src1);
|
|
|
| + Variable *makeExtract(Operand *Src, Operand *Index);
|
| +
|
| /// 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) {
|
| + void scalarizeInstruction(
|
| + Variable *Dest,
|
| + std::function<Inst *(Variable *, Variable *)> insertScalarInstruction,
|
| + Operand *Src0) {
|
| + 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);
|
| + auto *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);
|
| + auto *Op0 = makeExtract(Src0, 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.
|
| + auto *Res = Func->makeVariable(DestElementTy);
|
| + auto *Arith = insertScalarInstruction(Res, Op0);
|
| genTargetHelperCallFor(Arith);
|
|
|
| - // Insert the result into position.
|
| Variable *DestT = Func->makeVariable(DestTy);
|
| Context.insert<InstInsertElement>(DestT, T, Res, Index);
|
| T = DestT;
|
| @@ -509,33 +508,65 @@ protected:
|
| Context.insert<InstAssign>(Dest, T);
|
| }
|
|
|
| - template <typename F>
|
| - void scalarizeUnaryInstruction(Variable *Dest, Operand *Src0,
|
| - F &&MakeInstruction) {
|
| + void
|
| + scalarizeInstruction(Variable *Dest,
|
| + std::function<Inst *(Variable *, Variable *, Variable *)>
|
| + insertScalarInstruction,
|
| + Operand *Src0, Operand *Src1) {
|
| + 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());
|
|
|
| - assert(NumElements == typeNumElements(Src0->getType()));
|
| + Variable *T = Func->makeVariable(DestTy);
|
| + Context.insert<InstFakeDef>(T);
|
| +
|
| + for (SizeT I = 0; I < NumElements; ++I) {
|
| + auto *Index = Ctx->getConstantInt32(I);
|
| +
|
| + auto *Op0 = makeExtract(Src0, Index);
|
| + auto *Op1 = makeExtract(Src1, Index);
|
| +
|
| + // Perform the operation as a scalar operation.
|
| + auto *Res = Func->makeVariable(DestElementTy);
|
| + auto *Arith = insertScalarInstruction(Res, Op0, Op1);
|
| + genTargetHelperCallFor(Arith);
|
| +
|
| + Variable *DestT = Func->makeVariable(DestTy);
|
| + Context.insert<InstInsertElement>(DestT, T, Res, Index);
|
| + T = DestT;
|
| + }
|
| + Context.insert<InstAssign>(Dest, T);
|
| + }
|
| +
|
| + void scalarizeInstruction(
|
| + Variable *Dest, std::function<Inst *(Variable *, Variable *, Variable *,
|
| + Variable *)> insertScalarInstruction,
|
| + Operand *Src0, Operand *Src1, Operand *Src2) {
|
| + 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);
|
|
|
| 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);
|
|
|
| - // Extract the next two inputs.
|
| - Variable *Op0 = Func->makeVariable(Src0ElementTy);
|
| - Context.insert<InstExtractElement>(Op0, Src0, Index);
|
| + auto *Op0 = makeExtract(Src0, Index);
|
| + auto *Op1 = makeExtract(Src1, Index);
|
| + auto *Op2 = makeExtract(Src2, Index);
|
|
|
| // 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, Op0, Op1, Op2);
|
| genTargetHelperCallFor(Arith);
|
|
|
| - // Insert the result into position.
|
| Variable *DestT = Func->makeVariable(DestTy);
|
| Context.insert<InstInsertElement>(DestT, T, Res, Index);
|
| T = DestT;
|
|
|