Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions llvm/lib/Target/AIE/AIE2InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1434,6 +1434,75 @@ AIE2InstrInfo::getZOLSupport() const {
return Result;
}

bool AIE2InstrInfo::isOffsetInImmediateRange(
unsigned Opcode, unsigned LoadStoreSize,
std::optional<APInt> Offset) const {
if (!Offset)
return false;

switch (Opcode) {
case AIE2::G_AIE_OFFSET_LOAD:
case AIE2::G_AIE_OFFSET_STORE: {
switch (LoadStoreSize) {
case 8:
case 16:
return checkSignedImmediateRange<3, 1>(Offset);
case 20:
case 32:
return checkSignedImmediateRange<6, 4>(Offset);
case 128:
return checkSignedImmediateRange<6, 16>(Offset);
case 256:
return checkSignedImmediateRange<6, 32>(Offset);
case 512:
return checkSignedImmediateRangeSplitting<6, 32, 32>(Offset);
default:
return false;
}
}
case AIE2::G_AIE_POSTINC_LOAD:
case AIE2::G_AIE_POSTINC_STORE: {
switch (LoadStoreSize) {
case 8:
case 16:
return checkSignedImmediateRange<4, 1>(Offset);
case 20:
case 32:
return checkSignedImmediateRange<7, 4>(Offset);
case 128:
return checkSignedImmediateRange<7, 16>(Offset);
case 256:
case 512:
return checkSignedImmediateRange<7, 32>(Offset);
default:
return false;
}
}
case AIE2::G_AIE_OFFSET_ZEXTLOAD:
case AIE2::G_AIE_OFFSET_SEXTLOAD: {
switch (LoadStoreSize) {
case 8:
case 16:
return checkSignedImmediateRange<3, 1>(Offset);
default:
return false;
}
}
case AIE2::G_AIE_POSTINC_SEXTLOAD:
case AIE2::G_AIE_POSTINC_ZEXTLOAD: {
switch (LoadStoreSize) {
case 8:
case 16:
return checkSignedImmediateRange<4, 1>(Offset);
default:
return false;
}
}
default:
return false;
}
}

unsigned AIE2InstrInfo::getPseudoJNZDOpcode() const { return AIE2::PseudoJNZD; }

unsigned AIE2InstrInfo::getNumBypassedCycles(const InstrItineraryData *ItinData,
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/AIE/AIE2InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ class AIE2InstrInfo : public AIE2GenInstrInfo {

virtual std::optional<ZOLSupport> getZOLSupport() const override;

virtual bool
isOffsetInImmediateRange(unsigned Opcode, unsigned LoadStoreSize,
std::optional<APInt> Immediate) const override;

virtual unsigned getPseudoJNZDOpcode() const override;

unsigned getNumBypassedCycles(const InstrItineraryData *ItinData,
Expand Down
161 changes: 65 additions & 96 deletions llvm/lib/Target/AIE/AIE2InstructionSelector.cpp

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions llvm/lib/Target/AIE/AIEBaseInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ struct AIEBaseInstrInfo : public TargetInstrInfo {
// of bundles.
unsigned LoopSetupDistance;
};
virtual bool isOffsetInImmediateRange(unsigned Opcode, unsigned LoadStoreSize,
Copy link
Collaborator

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.

std::optional<APInt> Offset) const {
llvm_unreachable("Target didn't implement OffsetFitImmRange");
Copy link
Collaborator

Choose a reason for hiding this comment

The 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 {
Expand Down Expand Up @@ -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
18 changes: 0 additions & 18 deletions llvm/lib/Target/AIE/AIEBaseInstructionSelector.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,24 +198,6 @@ inline unsigned getLoadStoreSize(const MachineInstr &MI) {
return (*MI.memoperands_begin())->getSizeInBits().getValue();
}

template <unsigned NumEncodingBits, unsigned Step>
bool checkImmediateRange(std::optional<APInt> Immediate) {
unsigned MaxPow2 = NumEncodingBits + llvm::Log2_64(Step);
if (Immediate && isIntN(MaxPow2, Immediate->getSExtValue()) &&
Immediate->getSExtValue() % Step == 0) {
LLVM_DEBUG(dbgs() << "Immediate " << Immediate << " is valid for MaxPow2 "
<< MaxPow2 << " and Step " << Step << ".\n");
return true;
}
return false;
}

template <unsigned NumEncodingBits, unsigned Step, unsigned SplitOffset>
bool checkImmediateRangeSplitting(std::optional<APInt> Immediate) {
return Immediate && checkImmediateRange<NumEncodingBits, Step>(Immediate) &&
checkImmediateRange<NumEncodingBits, Step>(*Immediate + SplitOffset);
}

inline unsigned deriveRegBankID(Register Reg, const MachineRegisterInfo &MRI,
const RegisterBankInfo &RBI) {
const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
Expand Down
71 changes: 71 additions & 0 deletions llvm/lib/Target/AIE/aie2p/AIE2PInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,77 @@ AIE2PInstrInfo::getZOLSupport() const {
return Result;
}

bool AIE2PInstrInfo::isOffsetInImmediateRange(
unsigned Opcode, unsigned LoadStoreSize,
std::optional<APInt> Offset) const {
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);
Copy link
Collaborator

Choose a reason for hiding this comment

The 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;
}
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AIE/aie2p/AIE2PInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ class AIE2PInstrInfo : public AIE2PGenInstrInfo {

virtual std::optional<ZOLSupport> getZOLSupport() const override;

bool isOffsetInImmediateRange(unsigned Opcode, unsigned LoadStoreSize,
std::optional<APInt> Immediate) const override;

unsigned getNumBypassedCycles(const InstrItineraryData *ItinData,
const MachineInstr &DefMI, unsigned DefIdx,
const MachineInstr &UseMI,
Expand Down
Loading