diff options
author | Michael Bedy <Michael.Bedy@amd.com> | 2024-06-20 15:59:08 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-20 15:59:08 -0400 |
commit | edf2d0a95e9f0bd1befd8ff7686cb0e07af14fc3 (patch) | |
tree | 650b0ebe48b11d409a0c6654028ad25b55ba4432 /llvm/lib/Target | |
parent | 9473e162b92a7e0bb1471eaaa6cbd6b5fc104fed (diff) | |
download | llvm-edf2d0a95e9f0bd1befd8ff7686cb0e07af14fc3.zip llvm-edf2d0a95e9f0bd1befd8ff7686cb0e07af14fc3.tar.gz llvm-edf2d0a95e9f0bd1befd8ff7686cb0e07af14fc3.tar.bz2 |
[AMDGPU] Introduce a pseudo mnemonic for S_DELAY_ALU in MIR. (#96004)
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.cpp | 151 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h | 23 |
2 files changed, 174 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.cpp index 6ec41780..11f0cba 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.cpp @@ -17,6 +17,157 @@ using namespace llvm; +void AMDGPUMIRFormatter::printImm(raw_ostream &OS, const MachineInstr &MI, + std::optional<unsigned int> OpIdx, int64_t Imm) const { + + switch (MI.getOpcode()) { + case AMDGPU::S_DELAY_ALU: + assert(OpIdx == 0); + printSDelayAluImm(Imm, OS); + break; + default: + MIRFormatter::printImm(OS, MI, OpIdx, Imm); + break; + } +} + +/// Implement target specific parsing of immediate mnemonics. The mnemonic is +/// a string with a leading dot. +bool AMDGPUMIRFormatter::parseImmMnemonic(const unsigned OpCode, + const unsigned OpIdx, + StringRef Src, int64_t &Imm, + ErrorCallbackType ErrorCallback) const +{ + + switch (OpCode) { + case AMDGPU::S_DELAY_ALU: + return parseSDelayAluImmMnemonic(OpIdx, Imm, Src, ErrorCallback); + default: + break; + } + return true; // Don't know what this is +} + +void AMDGPUMIRFormatter::printSDelayAluImm(int64_t Imm, + llvm::raw_ostream &OS) const { + // Construct an immediate string to represent the information encoded in the + // s_delay_alu immediate. + // .id0_<dep>[_skip_<count>_id1<dep>] + constexpr int64_t None = 0; + constexpr int64_t Same = 0; + + uint64_t Id0 = (Imm & 0xF); + uint64_t Skip = ((Imm >> 4) & 0x7); + uint64_t Id1 = ((Imm >> 7) & 0xF); + auto Outdep = [&](uint64_t Id) { + if (Id == None) + OS << "NONE"; + else if (Id < 5) + OS << "VALU_DEP_" << Id; + else if (Id < 8) + OS << "TRANS32_DEP_" << Id - 4; + else + OS << "SALU_CYCLE_" << Id - 8; + }; + + OS << ".id0_"; + Outdep(Id0); + + // If the second inst is "same" and "none", no need to print the rest of the + // string. + if (Skip == Same && Id1 == None) + return; + + // Encode the second delay specification. + OS << "_skip_"; + if (Skip == 0) + OS << "SAME"; + else if (Skip == 1) + OS << "NEXT"; + else + OS << "SKIP_" << Skip - 1; + + OS << "_id1_"; + Outdep(Id1); +} + +bool AMDGPUMIRFormatter::parseSDelayAluImmMnemonic( + const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src, + llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const +{ + assert(OpIdx == 0); + + Imm = 0; + bool Expected = Src.consume_front(".id0_"); + if (!Expected) + return ErrorCallback(Src.begin(), "Expected .id0_"); + + auto ExpectInt = [&](StringRef &Src, int64_t Offset) -> int64_t { + int64_t Dep; + if (!Src.consumeInteger(10, Dep)) + return Dep + Offset; + + return -1; + }; + + auto DecodeDelay = [&](StringRef &Src) -> int64_t { + if (Src.consume_front("NONE")) + return 0; + if (Src.consume_front("VALU_DEP_")) + return ExpectInt(Src, 0); + if (Src.consume_front("TRANS32_DEP_")) + return ExpectInt(Src, 4); + if (Src.consume_front("SALU_CYCLE_")) + return ExpectInt(Src, 8); + + return -1; + }; + + int64_t Delay0 = DecodeDelay(Src); + int64_t Skip = 0; + int64_t Delay1 = 0; + if (Delay0 == -1) + return ErrorCallback(Src.begin(), "Could not decode delay0"); + + + // Set the Imm so far, to that early return has the correct value. + Imm = Delay0; + + // If that was the end of the string, the second instruction is "same" and + // "none" + if (Src.begin() == Src.end()) + return false; + + Expected = Src.consume_front("_skip_"); + if (!Expected) + return ErrorCallback(Src.begin(), "Expected _skip_"); + + + if (Src.consume_front("SAME")) { + Skip = 0; + } else if (Src.consume_front("NEXT")) { + Skip = 1; + } else if (Src.consume_front("SKIP_")) { + if (Src.consumeInteger(10, Skip)) { + return ErrorCallback(Src.begin(), "Expected integer Skip value"); + } + Skip += 1; + } else { + ErrorCallback(Src.begin(), "Unexpected Skip Value"); + } + + Expected = Src.consume_front("_id1_"); + if (!Expected) + return ErrorCallback(Src.begin(), "Expected _id1_"); + + Delay1 = DecodeDelay(Src); + if (Delay1 == -1) + return ErrorCallback(Src.begin(), "Could not decode delay1"); + + Imm = Imm | (Skip << 4) | (Delay1 << 7); + return false; +} + bool AMDGPUMIRFormatter::parseCustomPseudoSourceValue( StringRef Src, MachineFunction &MF, PerFunctionMIParsingState &PFS, const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h b/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h index 98b5031..c5c9473 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h @@ -28,12 +28,35 @@ public: AMDGPUMIRFormatter() = default; virtual ~AMDGPUMIRFormatter() = default; + /// Implement target specific printing for machine operand immediate value, so + /// that we can have more meaningful mnemonic than a 64-bit integer. Passing + /// None to OpIdx means the index is unknown. + virtual void printImm(raw_ostream &OS, const MachineInstr &MI, + std::optional<unsigned> OpIdx, + int64_t Imm) const override; + + /// Implement target specific parsing of immediate mnemonics. The mnemonic is + /// a string with a leading dot. + virtual bool parseImmMnemonic(const unsigned OpCode, const unsigned OpIdx, + StringRef Src, int64_t &Imm, + ErrorCallbackType ErrorCallback) const override; + /// Implement target specific parsing of target custom pseudo source value. bool parseCustomPseudoSourceValue(StringRef Src, MachineFunction &MF, PerFunctionMIParsingState &PFS, const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const override; + +private: + /// Print the string to represent s_delay_alu immediate value + void printSDelayAluImm(int64_t Imm, llvm::raw_ostream &OS) const; + + /// Parse the immediate pseudo literal for s_delay_alu + bool parseSDelayAluImmMnemonic( + const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src, + llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const; + }; } // end namespace llvm |