Adds support for SPV_INTEL_optnone.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
This is a draft patch - I want to discuss somethings inline.
The output for optnone.ll is:
bin/llc -O0 -mtriple=spirv32-unknown-unknown ../llvm/test/CodeGen/SPIRV/optnone.ll -o - OpCapability Kernel OpCapability Addresses OpCapability Linkage %1 = OpExtInstImport "OpenCL.std" OpMemoryModel Physical32 OpenCL OpExecutionMode %4 ContractionOff OpSource Unknown 0 OpName %4 "_Z3foov" OpDecorate %4 LinkageAttributes "_Z3foov" Export %2 = OpTypeVoid %3 = OpTypeFunction %2 OpCapability OptNoneINTEL ; -- Begin function _Z3foov OpExtension "�" "�" "�" "�" "�" "�" %4 = OpFunction %2 DontInline %3 %5 = OpLabel OpReturn OpFunctionEnd
OpExtension emits some funky unicode characters, I feel like I am doing this incorrectly but similarly to what's being done in SPIRVAsmPrinter::outputGlobalRequirements() :
MCInst Inst; Inst.setOpcode(SPIRV::OpExtension); addStringImm(getSymbolicOperandMnemonic( SPIRV::OperandCategory::ExtensionOperand, Ext), Inst); outputMCInst(Inst);
The other issue is that afaiu the OpExtension declaractions need to come up the top of the module. How is this organized in the backend so that I can emit these at the top of the module? Do I need to add these to the module requirements somehow?
llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | ||
---|---|---|
127 ↗ | (On Diff #544243) | Is this the best place to issue the instruction or is it preferable to do so during lowering for each function? |
I just checked section 2.4 of the spirv spec and all caps and exts need to come at the beginning: https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_logical_layout_of_a_module
So actually, I will move this code to a pass on MFs that adds the required extension and caps to the module.
Thank you for the patch @pmatos!
The OpExtension instructions should be added earlier in the pipeline. If the OpExtension instruction is added explicitly to MIR, it should be added before SPIRVModuleAnalysis. All explicit OpExtension instructions are then collected in this method. Please take a look at the draft pull request adding an extension here -- this should also help address the issue with incorrect unicode characters printed out in the SPIR-V assembly.
There are draft patches splitting SPIRVModuleAnalysis into smaller passes on our GitHub, but this can be done later (I am currently a bit busy, but promise to get back to this in August).
Paulo, please also add a lit test which checks the new feature.
llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | ||
---|---|---|
127 ↗ | (On Diff #544243) | A more appropriate place to add the required capability is inside collectReqs() in SPIRVModuleAnalysis.cpp. As for the extension, I'm not sure we should add it by default, having a function with optnone. I assume that SPIRV translator issues OpExtension instructions if we pass a command line option (like this --spirv-ext=+SPV_INTEL_optnone) and have a corresponding trigger in IR (like a function with optnone). Probably other ways to enable desirable extensions are suitable (e.g. in module metadata). We don't have support for the command line option yet, perhaps it can be implemented inside SPIRVSubtarget::initAvailableExtensions using cl::opt<string> and string parsing. Then we check function's optnone and availability of the extension inside collectReqs() and add the extension, as we do with capabilities. |
llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | ||
---|---|---|
127 ↗ | (On Diff #544243) | Thanks Iliya, I think for now I will add it by default if there's a function with optnone. I think later once we get some command line arguments, we can make it optional depending on if the command line argument is present or not. I think Michal already has some code in this direction so I would prefer no to duplicate this. |
Add INTEL optnone work to PreLegalizer.
Alternatively this could be done on its own pass. Doing it here runs the risk
of just using the PreLegalizer to too much of this kind of work.
In any case we are now generating better code with extension
declaration and capability at the top of the function.
Current patch generates:
OpCapability Kernel OpCapability Addresses OpCapability Linkage OpCapability OptNoneINTEL OpExtension "SPV_INTEL_optnone" %1 = OpExtInstImport "OpenCL.std" OpMemoryModel Physical32 OpenCL OpExecutionMode %4 ContractionOff OpSource Unknown 0 OpName %4 "_Z3foov" OpDecorate %4 LinkageAttributes "_Z3foov" Export %2 = OpTypeVoid %3 = OpTypeFunction %2 %4 = OpFunction %2 DontInline %3 ; -- Begin function _Z3foov %5 = OpLabel OpReturn OpFunctionEnd ; -- End function
which looks good to me. If you think this approach works well, I will tidy up the patch and fix up the test.
The output code is Ok and these instructions can be generated at this place. However, I think it's better to make such instructions as late as possible. If we insert this code into collectReqs (SPIRVModuleAnalysis.cpp), the output will be the same:
@@ -898,6 +902,12 @@ static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI, MAI.Reqs.getAndAddRequirements( SPIRV::OperandCategory::ExecutionModeOperand, SPIRV::ExecutionMode::VecTypeHint, ST); + if (F.hasOptNone() && + ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) { + // Output OpCapability OptNoneINTEL. + MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_optnone); + MAI.Reqs.addCapability(SPIRV::Capability::OptNoneINTEL); + } } }
but we even don't generate the instructions in IR (since we add exts and caps directly to requirements), so IR becomes simpler and there is less work for the backend.
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | ||
---|---|---|
587–596 ↗ | (On Diff #545553) | Please format this code properly (i.e. you can apply clang-format to all c++ files). |
llvm/test/CodeGen/SPIRV/optnone.ll | ||
18 | Don't need this empty line? | |
19–22 | Is it necessary to move this check after the foo() declaration? Maybe it's better to leave it in the same place and put OpCapability/OpExtension checks before it. |
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | ||
---|---|---|
555 | Please add '.' at the end of the sentence. |
Please add '.' at the end of the sentence.