From ba90cee0f19a1e7614c472b4571880c20936f22f Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Tue, 28 Jul 2015 23:02:45 +0000 Subject: [PATCH] MIR Serialization: Serialize the target index machine operands. Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243497 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetInstrInfo.h | 10 +++ lib/CodeGen/MIRParser/MILexer.cpp | 1 + lib/CodeGen/MIRParser/MILexer.h | 1 + lib/CodeGen/MIRParser/MIParser.cpp | 49 ++++++++++++++ lib/CodeGen/MIRPrinter.cpp | 23 +++++++ lib/Target/AMDGPU/AMDGPUInstrInfo.cpp | 11 ++++ lib/Target/AMDGPU/AMDGPUInstrInfo.h | 3 + .../MIR/AMDGPU/expected-target-index-name.mir | 65 ++++++++++++++++++ .../AMDGPU/invalid-target-index-operand.mir | 65 ++++++++++++++++++ test/CodeGen/MIR/AMDGPU/lit.local.cfg | 2 + .../MIR/AMDGPU/target-index-operands.mir | 66 +++++++++++++++++++ 11 files changed, 296 insertions(+) create mode 100644 test/CodeGen/MIR/AMDGPU/expected-target-index-name.mir create mode 100644 test/CodeGen/MIR/AMDGPU/invalid-target-index-operand.mir create mode 100644 test/CodeGen/MIR/AMDGPU/lit.local.cfg create mode 100644 test/CodeGen/MIR/AMDGPU/target-index-operands.mir diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 893ea9c887c..370e85a15c9 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -1262,6 +1262,16 @@ public: return 5; } + /// Return an array that contains the ids of the target indices (used for the + /// TargetIndex machine operand) and their names. + /// + /// MIR Serialization is able to serialize only the target indices that are + /// defined by this method. + virtual ArrayRef> + getSerializableTargetIndices() const { + return None; + } + private: unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode; }; diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index e2b378a7559..f7475a10ba9 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -148,6 +148,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register) .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset) .Case("blockaddress", MIToken::kw_blockaddress) + .Case("target-index", MIToken::kw_target_index) .Default(MIToken::Identifier); } diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index 8721ba858f9..7693c1015d8 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -52,6 +52,7 @@ struct MIToken { kw_cfi_def_cfa_register, kw_cfi_def_cfa_offset, kw_blockaddress, + kw_target_index, // Identifier tokens Identifier, diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index 135a36f2526..2ef76114331 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -82,6 +82,8 @@ class MIParser { StringMap Names2SubRegIndices; /// Maps from slot numbers to function's unnamed basic blocks. DenseMap Slots2BasicBlocks; + /// Maps from target index names to target indices. + StringMap Names2TargetIndices; public: MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error, @@ -127,6 +129,7 @@ public: bool parseCFIOperand(MachineOperand &Dest); bool parseIRBlock(BasicBlock *&BB, const Function &F); bool parseBlockAddressOperand(MachineOperand &Dest); + bool parseTargetIndexOperand(MachineOperand &Dest); bool parseMachineOperand(MachineOperand &Dest); private: @@ -173,6 +176,13 @@ private: void initSlots2BasicBlocks(); const BasicBlock *getIRBlock(unsigned Slot); + + void initNames2TargetIndices(); + + /// Try to convert a name of target index to the corresponding target index. + /// + /// Return true if the name isn't a name of a target index. + bool getTargetIndex(StringRef Name, int &Index); }; } // end anonymous namespace @@ -808,6 +818,24 @@ bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) { return false; } +bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { + assert(Token.is(MIToken::kw_target_index)); + lex(); + if (expectAndConsume(MIToken::lparen)) + return true; + if (Token.isNot(MIToken::Identifier)) + return error("expected the name of the target index"); + int Index = 0; + if (getTargetIndex(Token.stringValue(), Index)) + return error("use of undefined target index '" + Token.stringValue() + "'"); + lex(); + if (expectAndConsume(MIToken::rparen)) + return true; + // TODO: Parse the offset and target flags. + Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0); + return false; +} + bool MIParser::parseMachineOperand(MachineOperand &Dest) { switch (Token.kind()) { case MIToken::kw_implicit: @@ -846,6 +874,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) { return parseCFIOperand(Dest); case MIToken::kw_blockaddress: return parseBlockAddressOperand(Dest); + case MIToken::kw_target_index: + return parseTargetIndexOperand(Dest); case MIToken::Error: return true; case MIToken::Identifier: @@ -967,6 +997,25 @@ const BasicBlock *MIParser::getIRBlock(unsigned Slot) { return BlockInfo->second; } +void MIParser::initNames2TargetIndices() { + if (!Names2TargetIndices.empty()) + return; + const auto *TII = MF.getSubtarget().getInstrInfo(); + assert(TII && "Expected target instruction info"); + auto Indices = TII->getSerializableTargetIndices(); + for (const auto &I : Indices) + Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first)); +} + +bool MIParser::getTargetIndex(StringRef Name, int &Index) { + initNames2TargetIndices(); + auto IndexInfo = Names2TargetIndices.find(Name); + if (IndexInfo == Names2TargetIndices.end()) + return true; + Index = IndexInfo->second; + return false; +} + bool llvm::parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF, StringRef Src, const PerFunctionMIParsingState &PFS, diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index 24e9e381a13..e4395e0f52a 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -457,6 +457,18 @@ void MIPrinter::printStackObjectReference(int FrameIndex) { OS << '.' << Operand.Name; } +static const char *getTargetIndexName(const MachineFunction &MF, int Index) { + const auto *TII = MF.getSubtarget().getInstrInfo(); + assert(TII && "expected instruction info"); + auto Indices = TII->getSerializableTargetIndices(); + for (const auto &I : Indices) { + if (I.first == Index) { + return I.second; + } + } + return nullptr; +} + void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { switch (Op.getType()) { case MachineOperand::MO_Register: @@ -487,6 +499,17 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) { OS << "%const." << Op.getIndex(); // TODO: Print offset and target flags. break; + case MachineOperand::MO_TargetIndex: { + OS << "target-index("; + if (const auto *Name = getTargetIndexName( + *Op.getParent()->getParent()->getParent(), Op.getIndex())) + OS << Name; + else + OS << ""; + OS << ')'; + // TODO: Print the offset and target flags. + break; + } case MachineOperand::MO_JumpTableIndex: OS << "%jump-table." << Op.getIndex(); // TODO: Print target flags. diff --git a/lib/Target/AMDGPU/AMDGPUInstrInfo.cpp b/lib/Target/AMDGPU/AMDGPUInstrInfo.cpp index 1f215fc2d95..be9a34cb5d0 100644 --- a/lib/Target/AMDGPU/AMDGPUInstrInfo.cpp +++ b/lib/Target/AMDGPU/AMDGPUInstrInfo.cpp @@ -362,3 +362,14 @@ int AMDGPUInstrInfo::pseudoToMCOpcode(int Opcode) const { return MCOp; } + +ArrayRef> +AMDGPUInstrInfo::getSerializableTargetIndices() const { + static std::pair TargetIndices[] = { + {AMDGPU::TI_CONSTDATA_START, "amdgpu-constdata-start"}, + {AMDGPU::TI_SCRATCH_RSRC_DWORD0, "amdgpu-scratch-rsrc-dword0"}, + {AMDGPU::TI_SCRATCH_RSRC_DWORD1, "amdgpu-scratch-rsrc-dword1"}, + {AMDGPU::TI_SCRATCH_RSRC_DWORD2, "amdgpu-scratch-rsrc-dword2"}, + {AMDGPU::TI_SCRATCH_RSRC_DWORD3, "amdgpu-scratch-rsrc-dword3"}}; + return TargetIndices; +} diff --git a/lib/Target/AMDGPU/AMDGPUInstrInfo.h b/lib/Target/AMDGPU/AMDGPUInstrInfo.h index a69f4c0da72..bbfa70ecffb 100644 --- a/lib/Target/AMDGPU/AMDGPUInstrInfo.h +++ b/lib/Target/AMDGPU/AMDGPUInstrInfo.h @@ -145,6 +145,9 @@ public: return get(pseudoToMCOpcode(Opcode)); } + ArrayRef> + getSerializableTargetIndices() const override; + //===---------------------------------------------------------------------===// // Pure virtual funtions to be implemented by sub-classes. //===---------------------------------------------------------------------===// diff --git a/test/CodeGen/MIR/AMDGPU/expected-target-index-name.mir b/test/CodeGen/MIR/AMDGPU/expected-target-index-name.mir new file mode 100644 index 00000000000..9df6ba5f5d6 --- /dev/null +++ b/test/CodeGen/MIR/AMDGPU/expected-target-index-name.mir @@ -0,0 +1,65 @@ +# RUN: not llc -march=amdgcn -mcpu=SI -start-after postrapseudos -stop-after postrapseudos -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + %struct.foo = type { float, [5 x i32] } + + @float_gv = internal unnamed_addr addrspace(2) constant [5 x float] [float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00], align 4 + + define void @float(float addrspace(1)* %out, i32 %index) #0 { + entry: + %0 = getelementptr inbounds [5 x float], [5 x float] addrspace(2)* @float_gv, i32 0, i32 %index + %1 = load float, float addrspace(2)* %0 + store float %1, float addrspace(1)* %out + ret void + } + + declare { i1, i64 } @llvm.SI.if(i1) + + declare { i1, i64 } @llvm.SI.else(i64) + + declare i64 @llvm.SI.break(i64) + + declare i64 @llvm.SI.if.break(i1, i64) + + declare i64 @llvm.SI.else.break(i64, i64) + + declare i1 @llvm.SI.loop(i64) + + declare void @llvm.SI.end.cf(i64) + + attributes #0 = { "target-cpu"="SI" } + +... +--- +name: float +tracksSubRegLiveness: true +liveins: + - { reg: '%sgpr0_sgpr1' } +frameInfo: + maxAlignment: 8 +body: + - id: 0 + name: entry + liveins: [ '%sgpr0_sgpr1' ] + instructions: + - '%sgpr2_sgpr3 = S_GETPC_B64' +# CHECK: [[@LINE+1]]:50: expected the name of the target index + - '%sgpr2 = S_ADD_U32 %sgpr2, target-index(0), implicit-def %scc, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr3, 0, implicit-def %scc, implicit %scc, implicit-def %scc, implicit %scc' + - '%sgpr4_sgpr5 = S_LSHR_B64 %sgpr2_sgpr3, 32, implicit-def dead %scc' + - '%sgpr6 = S_LOAD_DWORD_IMM %sgpr0_sgpr1, 11' + - '%sgpr7 = S_ASHR_I32 %sgpr6, 31, implicit-def dead %scc' + - '%sgpr6_sgpr7 = S_LSHL_B64 %sgpr6_sgpr7, 2, implicit-def dead %scc' + - '%sgpr2 = S_ADD_U32 %sgpr2, @float_gv, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr4, 0, implicit-def dead %scc, implicit %scc' + - '%sgpr4 = S_ADD_U32 %sgpr2, %sgpr6, implicit-def %scc' + - '%sgpr5 = S_ADDC_U32 %sgpr3, %sgpr7, implicit-def dead %scc, implicit %scc' + - '%sgpr2 = S_LOAD_DWORD_IMM %sgpr4_sgpr5, 0' + - '%sgpr4_sgpr5 = S_LOAD_DWORDX2_IMM killed %sgpr0_sgpr1, 9' + - '%sgpr7 = S_MOV_B32 61440' + - '%sgpr6 = S_MOV_B32 -1' + - '%vgpr0 = V_MOV_B32_e32 killed %sgpr2, implicit %exec' + - 'BUFFER_STORE_DWORD_OFFSET killed %vgpr0, %sgpr4_sgpr5_sgpr6_sgpr7, 0, 0, 0, 0, 0, implicit %exec' + - S_ENDPGM +... diff --git a/test/CodeGen/MIR/AMDGPU/invalid-target-index-operand.mir b/test/CodeGen/MIR/AMDGPU/invalid-target-index-operand.mir new file mode 100644 index 00000000000..aeea9b2e3a5 --- /dev/null +++ b/test/CodeGen/MIR/AMDGPU/invalid-target-index-operand.mir @@ -0,0 +1,65 @@ +# RUN: not llc -march=amdgcn -mcpu=SI -start-after postrapseudos -stop-after postrapseudos -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + %struct.foo = type { float, [5 x i32] } + + @float_gv = internal unnamed_addr addrspace(2) constant [5 x float] [float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00], align 4 + + define void @float(float addrspace(1)* %out, i32 %index) #0 { + entry: + %0 = getelementptr inbounds [5 x float], [5 x float] addrspace(2)* @float_gv, i32 0, i32 %index + %1 = load float, float addrspace(2)* %0 + store float %1, float addrspace(1)* %out + ret void + } + + declare { i1, i64 } @llvm.SI.if(i1) + + declare { i1, i64 } @llvm.SI.else(i64) + + declare i64 @llvm.SI.break(i64) + + declare i64 @llvm.SI.if.break(i1, i64) + + declare i64 @llvm.SI.else.break(i64, i64) + + declare i1 @llvm.SI.loop(i64) + + declare void @llvm.SI.end.cf(i64) + + attributes #0 = { "target-cpu"="SI" } + +... +--- +name: float +tracksSubRegLiveness: true +liveins: + - { reg: '%sgpr0_sgpr1' } +frameInfo: + maxAlignment: 8 +body: + - id: 0 + name: entry + liveins: [ '%sgpr0_sgpr1' ] + instructions: + - '%sgpr2_sgpr3 = S_GETPC_B64' +# CHECK: [[@LINE+1]]:50: use of undefined target index 'constdata-start' + - '%sgpr2 = S_ADD_U32 %sgpr2, target-index(constdata-start), implicit-def %scc, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr3, 0, implicit-def %scc, implicit %scc, implicit-def %scc, implicit %scc' + - '%sgpr4_sgpr5 = S_LSHR_B64 %sgpr2_sgpr3, 32, implicit-def dead %scc' + - '%sgpr6 = S_LOAD_DWORD_IMM %sgpr0_sgpr1, 11' + - '%sgpr7 = S_ASHR_I32 %sgpr6, 31, implicit-def dead %scc' + - '%sgpr6_sgpr7 = S_LSHL_B64 %sgpr6_sgpr7, 2, implicit-def dead %scc' + - '%sgpr2 = S_ADD_U32 %sgpr2, @float_gv, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr4, 0, implicit-def dead %scc, implicit %scc' + - '%sgpr4 = S_ADD_U32 %sgpr2, %sgpr6, implicit-def %scc' + - '%sgpr5 = S_ADDC_U32 %sgpr3, %sgpr7, implicit-def dead %scc, implicit %scc' + - '%sgpr2 = S_LOAD_DWORD_IMM %sgpr4_sgpr5, 0' + - '%sgpr4_sgpr5 = S_LOAD_DWORDX2_IMM killed %sgpr0_sgpr1, 9' + - '%sgpr7 = S_MOV_B32 61440' + - '%sgpr6 = S_MOV_B32 -1' + - '%vgpr0 = V_MOV_B32_e32 killed %sgpr2, implicit %exec' + - 'BUFFER_STORE_DWORD_OFFSET killed %vgpr0, %sgpr4_sgpr5_sgpr6_sgpr7, 0, 0, 0, 0, 0, implicit %exec' + - S_ENDPGM +... diff --git a/test/CodeGen/MIR/AMDGPU/lit.local.cfg b/test/CodeGen/MIR/AMDGPU/lit.local.cfg new file mode 100644 index 00000000000..2a665f06be7 --- /dev/null +++ b/test/CodeGen/MIR/AMDGPU/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'AMDGPU' in config.root.targets: + config.unsupported = True diff --git a/test/CodeGen/MIR/AMDGPU/target-index-operands.mir b/test/CodeGen/MIR/AMDGPU/target-index-operands.mir new file mode 100644 index 00000000000..a130689419a --- /dev/null +++ b/test/CodeGen/MIR/AMDGPU/target-index-operands.mir @@ -0,0 +1,66 @@ +# RUN: llc -march=amdgcn -mcpu=SI -start-after postrapseudos -stop-after postrapseudos -o /dev/null %s | FileCheck %s +# This test verifies that the MIR parser can parse target index operands. + +--- | + + %struct.foo = type { float, [5 x i32] } + + @float_gv = internal unnamed_addr addrspace(2) constant [5 x float] [float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00], align 4 + + define void @float(float addrspace(1)* %out, i32 %index) #0 { + entry: + %0 = getelementptr inbounds [5 x float], [5 x float] addrspace(2)* @float_gv, i32 0, i32 %index + %1 = load float, float addrspace(2)* %0 + store float %1, float addrspace(1)* %out + ret void + } + + declare { i1, i64 } @llvm.SI.if(i1) + + declare { i1, i64 } @llvm.SI.else(i64) + + declare i64 @llvm.SI.break(i64) + + declare i64 @llvm.SI.if.break(i1, i64) + + declare i64 @llvm.SI.else.break(i64, i64) + + declare i1 @llvm.SI.loop(i64) + + declare void @llvm.SI.end.cf(i64) + + attributes #0 = { "target-cpu"="SI" } + +... +--- +name: float +tracksSubRegLiveness: true +liveins: + - { reg: '%sgpr0_sgpr1' } +frameInfo: + maxAlignment: 8 +body: + - id: 0 + name: entry + liveins: [ '%sgpr0_sgpr1' ] + instructions: + - '%sgpr2_sgpr3 = S_GETPC_B64' +# CHECK: %sgpr2 = S_ADD_U32 %sgpr2, target-index(amdgpu-constdata-start), implicit-def %scc, implicit-def %scc + - '%sgpr2 = S_ADD_U32 %sgpr2, target-index(amdgpu-constdata-start), implicit-def %scc, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr3, 0, implicit-def %scc, implicit %scc, implicit-def %scc, implicit %scc' + - '%sgpr4_sgpr5 = S_LSHR_B64 %sgpr2_sgpr3, 32, implicit-def dead %scc' + - '%sgpr6 = S_LOAD_DWORD_IMM %sgpr0_sgpr1, 11' + - '%sgpr7 = S_ASHR_I32 %sgpr6, 31, implicit-def dead %scc' + - '%sgpr6_sgpr7 = S_LSHL_B64 %sgpr6_sgpr7, 2, implicit-def dead %scc' + - '%sgpr2 = S_ADD_U32 %sgpr2, @float_gv, implicit-def %scc' + - '%sgpr3 = S_ADDC_U32 %sgpr4, 0, implicit-def dead %scc, implicit %scc' + - '%sgpr4 = S_ADD_U32 %sgpr2, %sgpr6, implicit-def %scc' + - '%sgpr5 = S_ADDC_U32 %sgpr3, %sgpr7, implicit-def dead %scc, implicit %scc' + - '%sgpr2 = S_LOAD_DWORD_IMM %sgpr4_sgpr5, 0' + - '%sgpr4_sgpr5 = S_LOAD_DWORDX2_IMM killed %sgpr0_sgpr1, 9' + - '%sgpr7 = S_MOV_B32 61440' + - '%sgpr6 = S_MOV_B32 -1' + - '%vgpr0 = V_MOV_B32_e32 killed %sgpr2, implicit %exec' + - 'BUFFER_STORE_DWORD_OFFSET killed %vgpr0, %sgpr4_sgpr5_sgpr6_sgpr7, 0, 0, 0, 0, 0, implicit %exec' + - S_ENDPGM +...