@@ -920,6 +920,10 @@ static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex,
920920 } else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
921921 Reqs.addRequirements (SPIRV::Capability::FPMaxErrorINTEL);
922922 Reqs.addExtension (SPIRV::Extension::SPV_INTEL_fp_max_error);
923+ } else if (Dec == SPIRV::Decoration::StallEnableINTEL) {
924+ Reqs.addRequirements (SPIRV::Capability::FPGAClusterAttributesINTEL);
925+ } else if (Dec == SPIRV::Decoration::StallFreeINTEL) {
926+ Reqs.addRequirements (SPIRV::Capability::FPGAClusterAttributesV2INTEL);
923927 }
924928}
925929
@@ -1976,6 +1980,68 @@ static void handleMIFlagDecoration(MachineInstr &I, const SPIRVSubtarget &ST,
19761980 buildOpDecorate (DstReg, I, TII, SPIRV::Decoration::FPFastMathMode, {FMFlags});
19771981}
19781982
1983+ static std::vector<uint32_t >
1984+ getMetaDataValues (std::vector<llvm::MDNode *> &MetaDataList) {
1985+ std::vector<uint32_t > res;
1986+ for (auto metaDataNode : MetaDataList) {
1987+ if (metaDataNode->getNumOperands () > 0 ) {
1988+ if (auto *CMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(
1989+ metaDataNode->getOperand (0 ))) {
1990+ if (auto *CI = llvm::dyn_cast<llvm::ConstantInt>(CMD->getValue ())) {
1991+ APInt val = CI->getValue ();
1992+ int64_t decVal = val.getZExtValue ();
1993+ res.push_back (decVal);
1994+ }
1995+ }
1996+ }
1997+ }
1998+ return res;
1999+ }
2000+
2001+ static void handleFunctionDecoration (llvm::Module::const_iterator F,
2002+ const SPIRVInstrInfo &TII,
2003+ MachineModuleInfo *MMI,
2004+ const SPIRVSubtarget &ST) {
2005+ MachineFunction *MF = MMI->getMachineFunction (*F);
2006+ Register FuncReg;
2007+ MachineInstr *FirstInstr = nullptr ;
2008+ llvm::SmallVector<std::pair<unsigned int , llvm::MDNode *>> MetaDataList;
2009+ // Find function register and first instruction
2010+ for (auto &MBB : *MF) {
2011+ for (auto &MI : MBB) {
2012+ if (MI.getOpcode () == SPIRV::OpFunction) {
2013+ FirstInstr = &MI;
2014+ FuncReg = MI.getOperand (0 ).getReg ();
2015+ break ;
2016+ }
2017+ }
2018+ if (FuncReg.isValid () && FirstInstr)
2019+ break ;
2020+ }
2021+ // Add function-level decorations based on metadata
2022+ F->getAllMetadata (MetaDataList);
2023+ for (auto &MetaData : MetaDataList) {
2024+ if (MetaData.second == F->getMetadata (" stall_enable" ) ||
2025+ MetaData.second == F->getMetadata (" stall_free" )) {
2026+ if (ST.canUseExtension (
2027+ SPIRV::Extension::SPV_INTEL_fpga_cluster_attributes)) {
2028+ std::vector<llvm::MDNode *> MetaDataVector;
2029+ MetaDataVector.push_back (MetaData.second );
2030+ std::vector<uint32_t > params = getMetaDataValues (MetaDataVector);
2031+ if (params.at (0 ) == 1 ) {
2032+ if (MetaData.second == F->getMetadata (" stall_enable" )) {
2033+ buildOpDecorate (FuncReg, *FirstInstr, TII,
2034+ SPIRV::Decoration::StallEnableINTEL, {});
2035+ } else {
2036+ buildOpDecorate (FuncReg, *FirstInstr, TII,
2037+ SPIRV::Decoration::StallFreeINTEL, {});
2038+ }
2039+ }
2040+ }
2041+ }
2042+ }
2043+ }
2044+
19792045// Walk all functions and add decorations related to MI flags.
19802046static void addDecorations (const Module &M, const SPIRVInstrInfo &TII,
19812047 MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
@@ -1987,6 +2053,8 @@ static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
19872053 for (auto &MBB : *MF)
19882054 for (auto &MI : MBB)
19892055 handleMIFlagDecoration (MI, ST, TII, MAI.Reqs );
2056+
2057+ handleFunctionDecoration (F, TII, MMI, ST);
19902058 }
19912059}
19922060
0 commit comments