From 25acd3b9d07265fa1aa1b140672b7caa66d7c76e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 2 Jun 2018 09:49:04 -0700 Subject: [PATCH] Moving the simdSizeOfHWIntrinsic and numArgsOfHWIntrinsic methods to be static methods on HWIntrinsicInfo --- src/jit/compiler.h | 8 +-- src/jit/gentree.cpp | 6 +-- src/jit/hwintrinsicArm64.cpp | 4 +- src/jit/hwintrinsicArm64.h | 1 + src/jit/hwintrinsiccodegenxarch.cpp | 6 +-- src/jit/hwintrinsicxarch.cpp | 80 ++++++++++++----------------- src/jit/hwintrinsicxarch.h | 3 ++ src/jit/lowerxarch.cpp | 2 +- src/jit/lsraarm64.cpp | 2 +- src/jit/lsraxarch.cpp | 2 +- 10 files changed, 53 insertions(+), 61 deletions(-) diff --git a/src/jit/compiler.h b/src/jit/compiler.h index a5dc916cf4..aa1f469d0a 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -1460,6 +1460,10 @@ class Compiler friend class ObjectAllocator; friend struct GenTree; +#ifdef FEATURE_HW_INTRINSICS + friend struct HWIntrinsicInfo; +#endif // FEATURE_HW_INTRINSICS + #ifndef _TARGET_64BIT_ friend class DecomposeLongs; #endif // !_TARGET_64BIT_ @@ -2959,9 +2963,6 @@ protected: CORINFO_SIG_INFO* sig, bool mustExpand); -public: - static int numArgsOfHWIntrinsic(GenTreeHWIntrinsic* node); - protected: #ifdef _TARGET_XARCH_ static bool isIntrinsicAnIsSupportedPropertyGetter(NamedIntrinsic intrinsic); @@ -3012,7 +3013,6 @@ protected: bool mustExpand); bool compSupportsHWIntrinsic(InstructionSet isa); bool isScalarISA(InstructionSet isa); - unsigned simdSizeOfHWIntrinsic(NamedIntrinsic intrinsic, CORINFO_SIG_INFO* sig); static GenTree* lastOpOfHWIntrinsic(GenTreeHWIntrinsic* node, int numArgs); protected: diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index fce62b7005..b40c026367 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -17583,7 +17583,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad() // Some AVX instructions here also have MemoryLoad sematics // Do we have 3 operands? - if (Compiler::numArgsOfHWIntrinsic(this) != 3) + if (HWIntrinsicInfo::lookupNumArgs(this) != 3) { return false; } @@ -17618,7 +17618,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore() // Some AVX instructions here also have MemoryStore sematics // Do we have 3 operands? - if (Compiler::numArgsOfHWIntrinsic(this) != 3) + if (HWIntrinsicInfo::lookupNumArgs(this) != 3) { return false; } @@ -17650,7 +17650,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoadOrStore() // Some AVX instructions here also have MemoryLoad or MemoryStore sematics // Do we have 3 operands? - if (Compiler::numArgsOfHWIntrinsic(this) != 3) + if (HWIntrinsicInfo::lookupNumArgs(this) != 3) { return false; } diff --git a/src/jit/hwintrinsicArm64.cpp b/src/jit/hwintrinsicArm64.cpp index c64ff6e464..280bd3eedc 100644 --- a/src/jit/hwintrinsicArm64.cpp +++ b/src/jit/hwintrinsicArm64.cpp @@ -139,7 +139,7 @@ bool Compiler::impCheckImmediate(GenTree* immediateOp, unsigned int max) } //------------------------------------------------------------------------ -// numArgsOfHWIntrinsic: gets the number of arguments for the hardware intrinsic. +// lookupNumArgs: gets the number of arguments for the hardware intrinsic. // This attempts to do a table based lookup but will fallback to the number // of operands in 'node' if the table entry is -1. // @@ -149,7 +149,7 @@ bool Compiler::impCheckImmediate(GenTree* immediateOp, unsigned int max) // Return Value: // number of arguments // -int Compiler::numArgsOfHWIntrinsic(GenTreeHWIntrinsic* node) +int HWIntrinsicInfo::lookupNumArgs(const GenTreeHWIntrinsic* node) { NamedIntrinsic intrinsic = node->gtHWIntrinsicId; diff --git a/src/jit/hwintrinsicArm64.h b/src/jit/hwintrinsicArm64.h index c0d3ffd360..e60288a26c 100644 --- a/src/jit/hwintrinsicArm64.h +++ b/src/jit/hwintrinsicArm64.h @@ -52,6 +52,7 @@ struct HWIntrinsicInfo instruction instrs[3]; static const HWIntrinsicInfo& lookup(NamedIntrinsic id); + static int lookupNumArgs(const GenTreeHWIntrinsic* node); static const char* lookupName(NamedIntrinsic id) { diff --git a/src/jit/hwintrinsiccodegenxarch.cpp b/src/jit/hwintrinsiccodegenxarch.cpp index fddf16233c..088e6d4a9f 100644 --- a/src/jit/hwintrinsiccodegenxarch.cpp +++ b/src/jit/hwintrinsiccodegenxarch.cpp @@ -56,7 +56,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsicId); int ival = HWIntrinsicInfo::lookupIval(intrinsicId); - int numArgs = Compiler::numArgsOfHWIntrinsic(node); + int numArgs = HWIntrinsicInfo::lookupNumArgs(node); assert((flags & HW_Flag_NoCodeGen) == 0); @@ -1429,7 +1429,7 @@ void CodeGen::genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node) emitAttr attr = EA_ATTR(node->gtSIMDSize); var_types targetType = node->TypeGet(); instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType); - int numArgs = Compiler::numArgsOfHWIntrinsic(node); + int numArgs = HWIntrinsicInfo::lookupNumArgs(node); GenTree* op1 = node->gtGetOp1(); GenTree* op2 = node->gtGetOp2(); regNumber op1Reg = REG_NA; @@ -1708,7 +1708,7 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node) GenTree* op1 = node->gtGetOp1(); regNumber targetReg = node->gtRegNum; - assert(Compiler::numArgsOfHWIntrinsic(node) == 3); + assert(HWIntrinsicInfo::lookupNumArgs(node) == 3); assert(op1 != nullptr); assert(op1->OperIsList()); assert(op1->gtGetOp2()->OperIsList()); diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp index b8e6deca07..55ead63a96 100644 --- a/src/jit/hwintrinsicxarch.cpp +++ b/src/jit/hwintrinsicxarch.cpp @@ -158,27 +158,23 @@ InstructionSet HWIntrinsicInfo::lookupIsa(const char* className) } //------------------------------------------------------------------------ -// simdSizeOfHWIntrinsic: get the SIMD size of this intrinsic +// lookupSimdSize: Gets the SimdSize for a given HWIntrinsic and signature // // Arguments: -// intrinsic -- id of the intrinsic function. +// id -- The ID associated with the HWIntrinsic to lookup +// sig -- The signature of the HWIntrinsic to lookup // // Return Value: -// the SIMD size of this intrinsic -// - from the hwIntrinsicInfoArray table if intrinsic has NO HW_Flag_UnfixedSIMDSize -// - from the signature if intrinsic has HW_Flag_UnfixedSIMDSize +// The SIMD size for the HWIntrinsic associated with id and sig // -// Note - this function is only used by the importer -// after importation (i.e., codegen), we can get the SIMD size from GenTreeHWIntrinsic IR -unsigned Compiler::simdSizeOfHWIntrinsic(NamedIntrinsic intrinsic, CORINFO_SIG_INFO* sig) +// Remarks: +// This function is only used by the importer. After importation, we can +// get the SIMD size from the GenTreeHWIntrinsic node. +unsigned HWIntrinsicInfo::lookupSimdSize(Compiler* comp, NamedIntrinsic id, CORINFO_SIG_INFO* sig) { - assert(intrinsic > NI_HW_INTRINSIC_START && intrinsic < NI_HW_INTRINSIC_END); - - HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsic); - - if ((flags & HW_Flag_UnfixedSIMDSize) == 0) + if ((lookupFlags(id) & HW_Flag_UnfixedSIMDSize) == 0) { - return hwIntrinsicInfoArray[intrinsic - NI_HW_INTRINSIC_START - 1].simdSize; + return lookupSimdSize(id); } CORINFO_CLASS_HANDLE typeHnd = nullptr; @@ -189,37 +185,31 @@ unsigned Compiler::simdSizeOfHWIntrinsic(NamedIntrinsic intrinsic, CORINFO_SIG_I } else { - assert((flags & HW_Flag_BaseTypeFromFirstArg) != 0); - typeHnd = info.compCompHnd->getArgClass(sig, sig->args); + assert((lookupFlags(id) & HW_Flag_BaseTypeFromFirstArg) != 0); + typeHnd = comp->info.compCompHnd->getArgClass(sig, sig->args); } unsigned simdSize = 0; - var_types baseType = getBaseTypeAndSizeOfSIMDType(typeHnd, &simdSize); - assert(simdSize > 0 && baseType != TYP_UNKNOWN); + var_types baseType = comp->getBaseTypeAndSizeOfSIMDType(typeHnd, &simdSize); + assert((simdSize > 0) && (baseType != TYP_UNKNOWN)); return simdSize; } //------------------------------------------------------------------------ -// numArgsOfHWIntrinsic: gets the number of arguments for the hardware intrinsic. -// This attempts to do a table based lookup but will fallback to the number -// of operands in 'node' if the table entry is -1. +// lookupNumArgs: Gets the number of args for a given HWIntrinsic // // Arguments: -// node -- GenTreeHWIntrinsic* node with nullptr default value +// node -- The HWIntrinsic node to get the number of args for // // Return Value: -// number of arguments -// -int Compiler::numArgsOfHWIntrinsic(GenTreeHWIntrinsic* node) +// The number of args for the HWIntrinsic associated with node +int HWIntrinsicInfo::lookupNumArgs(const GenTreeHWIntrinsic* node) { assert(node != nullptr); - NamedIntrinsic intrinsic = node->gtHWIntrinsicId; - - assert(intrinsic != NI_Illegal); - assert(intrinsic > NI_HW_INTRINSIC_START && intrinsic < NI_HW_INTRINSIC_END); + NamedIntrinsic id = node->gtHWIntrinsicId; + int numArgs = lookupNumArgs(id); - int numArgs = hwIntrinsicInfoArray[intrinsic - NI_HW_INTRINSIC_START - 1].numArgs; if (numArgs >= 0) { return numArgs; @@ -228,7 +218,6 @@ int Compiler::numArgsOfHWIntrinsic(GenTreeHWIntrinsic* node) assert(numArgs == -1); GenTree* op1 = node->gtGetOp1(); - GenTree* op2 = node->gtGetOp2(); if (op1 == nullptr) { @@ -237,26 +226,25 @@ int Compiler::numArgsOfHWIntrinsic(GenTreeHWIntrinsic* node) if (op1->OperIsList()) { - numArgs = 0; +#if DEBUG GenTreeArgList* list = op1->AsArgList(); + numArgs = 0; - while (list != nullptr) + do { numArgs++; list = list->Rest(); - } + } while (list != nullptr); - // We should only use a list if we have 3 operands. - assert(numArgs >= 3); - return numArgs; - } + assert(numArgs == 3); +#endif - if (op2 == nullptr) - { - return 1; + return 3; } - return 2; + GenTree* op2 = node->gtGetOp2(); + + return (op2 == nullptr) ? 1 : 2; } //------------------------------------------------------------------------ @@ -728,7 +716,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, // table-driven importer of simple intrinsics if (isTableDriven) { - unsigned simdSize = simdSizeOfHWIntrinsic(intrinsic, sig); + unsigned simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); CORINFO_ARG_LIST_HANDLE argList = sig->args; CORINFO_CLASS_HANDLE argClass; var_types argType = TYP_UNKNOWN; @@ -847,7 +835,7 @@ GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, GenTree* op2 = nullptr; GenTree* op3 = nullptr; GenTree* op4 = nullptr; - int simdSize = simdSizeOfHWIntrinsic(intrinsic, sig); + int simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); // The Prefetch and StoreFence intrinsics don't take any SIMD operands // and have a simdSize of 0 @@ -897,7 +885,7 @@ GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, GenTree* op1 = nullptr; GenTree* op2 = nullptr; int ival = -1; - int simdSize = simdSizeOfHWIntrinsic(intrinsic, sig); + int simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); var_types baseType = TYP_UNKNOWN; var_types retType = TYP_UNKNOWN; @@ -1031,7 +1019,7 @@ GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, GenTree* op1 = nullptr; GenTree* op2 = nullptr; var_types baseType = TYP_UNKNOWN; - int simdSize = simdSizeOfHWIntrinsic(intrinsic, sig); + int simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); switch (intrinsic) { diff --git a/src/jit/hwintrinsicxarch.h b/src/jit/hwintrinsicxarch.h index 2935057b35..51fb5fff9a 100644 --- a/src/jit/hwintrinsicxarch.h +++ b/src/jit/hwintrinsicxarch.h @@ -138,8 +138,11 @@ struct HWIntrinsicInfo HWIntrinsicFlag flags; static const HWIntrinsicInfo& lookup(NamedIntrinsic id); + static NamedIntrinsic lookupId(const char* className, const char* methodName); static InstructionSet lookupIsa(const char* className); + static unsigned lookupSimdSize(Compiler* comp, NamedIntrinsic id, CORINFO_SIG_INFO* sig); + static int lookupNumArgs(const GenTreeHWIntrinsic* node); // Member lookup diff --git a/src/jit/lowerxarch.cpp b/src/jit/lowerxarch.cpp index 11066becc7..ba9833ac4a 100644 --- a/src/jit/lowerxarch.cpp +++ b/src/jit/lowerxarch.cpp @@ -2505,7 +2505,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) NamedIntrinsic intrinsicID = node->gtHWIntrinsicId; HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicID); HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsicID); - int numArgs = Compiler::numArgsOfHWIntrinsic(node); + int numArgs = HWIntrinsicInfo::lookupNumArgs(node); var_types baseType = node->gtSIMDBaseType; GenTree* op1 = node->gtGetOp1(); diff --git a/src/jit/lsraarm64.cpp b/src/jit/lsraarm64.cpp index fbca9ae901..9cc17cacc0 100644 --- a/src/jit/lsraarm64.cpp +++ b/src/jit/lsraarm64.cpp @@ -1027,7 +1027,7 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) { NamedIntrinsic intrinsicID = intrinsicTree->gtHWIntrinsicId; - int numArgs = Compiler::numArgsOfHWIntrinsic(intrinsicTree); + int numArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicTree); GenTree* op1 = intrinsicTree->gtGetOp1(); GenTree* op2 = intrinsicTree->gtGetOp2(); diff --git a/src/jit/lsraxarch.cpp b/src/jit/lsraxarch.cpp index 15103100a4..43484f3d72 100644 --- a/src/jit/lsraxarch.cpp +++ b/src/jit/lsraxarch.cpp @@ -2295,7 +2295,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId); HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsicId); - int numArgs = Compiler::numArgsOfHWIntrinsic(intrinsicTree); + int numArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicTree); if ((isa == InstructionSet_AVX) || (isa == InstructionSet_AVX2)) { -- 2.34.1