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