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; |