-
Notifications
You must be signed in to change notification settings - Fork 30
[AIEX][NFC] refactor Load/Store Imm check #460
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,6 +59,10 @@ struct AIEBaseInstrInfo : public TargetInstrInfo { | |
| // of bundles. | ||
| unsigned LoopSetupDistance; | ||
| }; | ||
| virtual bool isOffsetInImmediateRange(unsigned Opcode, unsigned LoadStoreSize, | ||
| std::optional<APInt> Offset) const { | ||
| llvm_unreachable("Target didn't implement OffsetFitImmRange"); | ||
|
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. nit: message out of sync with function name |
||
| } | ||
|
|
||
| /// Return the opcode for a return instruction | ||
| virtual unsigned getReturnOpcode() const { | ||
|
|
@@ -748,6 +752,24 @@ struct AIEBaseInstrInfo : public TargetInstrInfo { | |
| const MIRFormatter *getMIRFormatter() const override; | ||
| mutable std::unique_ptr<AIEMIRFormatter> Formatter; | ||
| }; | ||
|
|
||
| template <unsigned NumEncodingBits, unsigned Step> | ||
| bool checkSignedImmediateRange(std::optional<APInt> Immediate) { | ||
| const unsigned MaxPow2 = NumEncodingBits + llvm::Log2_64(Step); | ||
| if (Immediate && isIntN(MaxPow2, Immediate->getSExtValue()) && | ||
| Immediate->getSExtValue() % Step == 0) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| template <unsigned NumEncodingBits, unsigned Step, unsigned SplitOffset> | ||
| bool checkSignedImmediateRangeSplitting(std::optional<APInt> Immediate) { | ||
| return Immediate && | ||
| checkSignedImmediateRange<NumEncodingBits, Step>(Immediate) && | ||
| checkSignedImmediateRange<NumEncodingBits, Step>(*Immediate + | ||
| SplitOffset); | ||
| } | ||
| } // namespace llvm | ||
|
|
||
| #endif // LLVM_LIB_TARGET_AIE_AIEBASEINSTRRINFO_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1733,6 +1733,77 @@ AIE2PInstrInfo::getZOLSupport() const { | |
| return Result; | ||
| } | ||
|
|
||
| bool AIE2PInstrInfo::isOffsetInImmediateRange( | ||
| unsigned Opcode, unsigned LoadStoreSize, | ||
| std::optional<APInt> Offset) const { | ||
F-Stuckmann marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (!Offset) | ||
| return false; | ||
|
|
||
| switch (Opcode) { | ||
| case AIE2P::G_AIE_OFFSET_STORE: | ||
| case AIE2P::G_AIE_OFFSET_LOAD: { | ||
| switch (LoadStoreSize) { | ||
| case 8: | ||
| return checkSignedImmediateRange<4, 1>(Offset); | ||
| case 16: | ||
| return checkSignedImmediateRange<4, 2>(Offset); | ||
| case 20: | ||
| case 32: | ||
| return checkSignedImmediateRange<4, 4>(Offset); | ||
| case 128: | ||
| return checkSignedImmediateRange<4, 16>(Offset); | ||
| case 256: | ||
| return checkSignedImmediateRange<4, 32>(Offset); | ||
| case 512: | ||
| return checkSignedImmediateRange<4, 64>(Offset); | ||
| case 1024: | ||
| return checkSignedImmediateRangeSplitting<4, 64, 64>(Offset); | ||
| case 2048: | ||
| return checkSignedImmediateRangeSplitting<4, 64, 192>(Offset); | ||
|
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. nit: I see that this checks 0 and 192, not the intermediate 64 and 128. I guess the implementation assumes that step divides splitoffset. Perhaps static_assert that? |
||
| default: | ||
| return false; | ||
| } | ||
| } | ||
| case AIE2P::G_AIE_OFFSET_SEXTLOAD: | ||
| case AIE2P::G_AIE_OFFSET_ZEXTLOAD: | ||
| case AIE2P::G_AIE_POSTINC_ZEXTLOAD: | ||
| case AIE2P::G_AIE_POSTINC_SEXTLOAD: { | ||
| switch (LoadStoreSize) { | ||
| case 8: | ||
| return checkSignedImmediateRange<4, 1>(Offset); | ||
| case 16: | ||
| return checkSignedImmediateRange<4, 2>(Offset); | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
| case AIE2P::G_AIE_POSTINC_STORE: | ||
| case AIE2P::G_AIE_POSTINC_LOAD: { | ||
| switch (LoadStoreSize) { | ||
| case 8: | ||
| return checkSignedImmediateRange<4, 1>(Offset); | ||
| case 16: | ||
| return checkSignedImmediateRange<4, 2>(Offset); | ||
| case 20: | ||
| case 32: | ||
| return checkSignedImmediateRange<4, 4>(Offset); | ||
| case 128: | ||
| return checkSignedImmediateRange<4, 16>(Offset); | ||
| case 256: | ||
| return checkSignedImmediateRange<4, 32>(Offset); | ||
| case 512: | ||
| case 1024: | ||
| case 2048: | ||
| return checkSignedImmediateRange<4, 64>(Offset); | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| unsigned AIE2PInstrInfo::getGenericAddVectorEltOpcode() const { | ||
| return AIE2P::G_AIE_ADD_VECTOR_ELT_HI; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a feeling that this may be a best guess for these generic opcodes. Perhaps document whether it should return true or false if there's uncertainty.