-
Notifications
You must be signed in to change notification settings - Fork 5.5k
[RyuJIT Wasm] SIMD Codegen for ExtractScalar/ReplaceScalar, Unsigned Compares #130272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 18 commits
fb61856
733ac6c
5e39af6
d6ef2cd
9fb2ff9
1d3a915
200327e
03074c8
24d8d06
de21e1c
0eba689
26eb5a9
7d842b0
d63e3d3
227b78c
3dc83dd
4e98a74
1cd93db
fc10e1a
7823f44
f94a3f6
af827a3
a70c71b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -106,7 +106,7 @@ void emitter::emitIns_I(instruction ins, emitAttr attr, cnsval_ssize_t imm) | |
| // ins - instruction to emit | ||
| // attr - emit attributes | ||
| // imm - immediate value (depth in control flow stack) | ||
| // targetBlock - block at that depth | ||
| // targetBlock - block at that depth (may be null, in the case of jump table which doesn't target a real block) | ||
| // | ||
| void emitter::emitIns_J(instruction ins, emitAttr attr, cnsval_ssize_t imm, BasicBlock* targetBlock) | ||
| { | ||
|
|
@@ -116,7 +116,7 @@ void emitter::emitIns_J(instruction ins, emitAttr attr, cnsval_ssize_t imm, Basi | |
| id->idIns(ins); | ||
| id->idInsFmt(fmt); | ||
|
|
||
| if (m_debugInfoSize > 0) | ||
| if (m_debugInfoSize > 0 && targetBlock != nullptr) | ||
| { | ||
| id->idDebugOnlyInfo()->idTargetBlock = targetBlock; | ||
| } | ||
|
|
@@ -463,14 +463,34 @@ void emitter::emitIns_V128Imm(instruction ins, const uint8_t bytes[16]) | |
| // | ||
| // Arguments: | ||
| // ins - instruction (e.g., INS_i8x16_extract_lane_s) | ||
| // attr - emit attribute indicating the lane element size | ||
| // laneIdx - lane index byte | ||
| // | ||
| void emitter::emitIns_Lane(instruction ins, emitAttr attr, uint8_t laneIdx) | ||
| void emitter::emitIns_Lane(instruction ins, uint8_t laneIdx) | ||
| { | ||
| instrDesc* id = emitNewInstrSC(attr, laneIdx); | ||
| insFormat fmt = emitInsFormat(ins); | ||
| uint8_t elemSize = CodeGenInterface::instSimdElemSize(ins); | ||
| uint8_t elemSize = CodeGenInterface::instSimdElemSize(ins); | ||
|
|
||
| // Add element width as an emit attribute | ||
| emitAttr attr = EA_UNKNOWN; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can this not just be
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I knew there had to be a helper to do this, thank you |
||
| switch (elemSize) | ||
|
adamperlin marked this conversation as resolved.
|
||
| { | ||
| case 1: | ||
| attr = EA_1BYTE; | ||
| break; | ||
| case 2: | ||
| attr = EA_2BYTE; | ||
| break; | ||
| case 4: | ||
| attr = EA_4BYTE; | ||
| break; | ||
| case 8: | ||
| attr = EA_8BYTE; | ||
| break; | ||
| default: | ||
| unreached(); | ||
| } | ||
|
|
||
| instrDesc* id = emitNewInstrSC(attr, laneIdx); | ||
| insFormat fmt = emitInsFormat(ins); | ||
| assert(fmt == IF_LANE); | ||
| assert(isValidVectorIndex(elemSize, laneIdx)); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -539,6 +539,10 @@ enum GenTreeFlags : unsigned | |
| #ifdef FEATURE_HW_INTRINSICS | ||
| GTF_HW_EM_OP = 0x10000000, // GT_HWINTRINSIC -- node is used as an operand to an embedded mask | ||
| GTF_HW_USER_CALL = 0x20000000, // GT_HWINTRINSIC -- node is implemented via a user call | ||
| #ifdef TARGET_WASM | ||
| GTF_HW_NEEDS_JUMP_TABLE = 0x40000000, // GT_HWINTRINSIC -- (WASM) intrinsic has a non-constant immediate | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is really a small optimization to avoid having to re-check the operands for a GT_HWINTRINSIC over and over again to see if a jump table is needed (this mostly comes up in regalloc, where we only need to mark the operands for an intrinsic as
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it expensive to do for wasm? On most platforms this is just checking
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The immediate value isn't always
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have to pull all the operands anyways, so is that necessarily a bad thing? The main concern I have is that the available GenTree flags are scarce. The need for a jump table is then expected to be rare and such nodes are rare enough that it's unlikely to even show up on the SPMI throughput tracking, so just doing this the "same way" as all other architectures (i.e. checking |
||
| // operand and requires a jump-table fallback at codegen | ||
| #endif // TARGET_WASM | ||
| #endif // FEATURE_HW_INTRINSICS | ||
| }; | ||
|
|
||
|
|
@@ -2456,6 +2460,19 @@ struct GenTree | |
| gtFlags |= GTF_HW_EM_OP; | ||
| } | ||
|
|
||
| #ifdef TARGET_WASM | ||
| bool NeedsJumpTableFallback() const | ||
| { | ||
| return OperIsHWIntrinsic() && ((gtFlags & GTF_HW_NEEDS_JUMP_TABLE) != 0); | ||
| } | ||
|
|
||
| void SetNeedsJumpTableFallback() | ||
| { | ||
| assert(OperIsHWIntrinsic()); | ||
| gtFlags |= GTF_HW_NEEDS_JUMP_TABLE; | ||
| } | ||
| #endif // TARGET_WASM | ||
|
|
||
| #endif // FEATURE_HW_INTRINSICS | ||
|
|
||
| static bool HandleKindDataIsInvariant(GenTreeFlags flags); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.