[SPIRV] Implement type deduction and reference to function declarations for indirect calls using SPV_INTEL_function_pointers (#111159)

This PR improves implementation of SPV_INTEL_function_pointers and type
inference for phi-nodes and indirect calls.
diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index 55b4162..8210e20 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -78,6 +78,11 @@
   void outputExecutionMode(const Module &M);
   void outputAnnotations(const Module &M);
   void outputModuleSections();
+  bool isHidden() {
+    return MF->getFunction()
+        .getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME)
+        .isValid();
+  }
 
   void emitInstruction(const MachineInstr *MI) override;
   void emitFunctionEntryLabel() override {}
@@ -131,7 +136,7 @@
   TII = ST->getInstrInfo();
   const Function &F = MF->getFunction();
 
-  if (isVerbose()) {
+  if (isVerbose() && !isHidden()) {
     OutStreamer->getCommentOS()
         << "-- Begin function "
         << GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n';
@@ -149,11 +154,18 @@
 
 // Emit OpFunctionEnd at the end of MF and clear BBNumToRegMap.
 void SPIRVAsmPrinter::emitFunctionBodyEnd() {
+  // Do not emit anything if it's an internal service function.
+  if (isHidden())
+    return;
   outputOpFunctionEnd();
   MAI->BBNumToRegMap.clear();
 }
 
 void SPIRVAsmPrinter::emitOpLabel(const MachineBasicBlock &MBB) {
+  // Do not emit anything if it's an internal service function.
+  if (isHidden())
+    return;
+
   MCInst LabelInst;
   LabelInst.setOpcode(SPIRV::OpLabel);
   LabelInst.addOperand(MCOperand::createReg(MAI->getOrCreateMBBRegister(MBB)));
@@ -162,7 +174,9 @@
 }
 
 void SPIRVAsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
-  assert(!MBB.empty() && "MBB is empty!");
+  // Do not emit anything if it's an internal service function.
+  if (MBB.empty())
+    return;
 
   // If it's the first MBB in MF, it has OpFunction and OpFunctionParameter, so
   // OpLabel should be output after them.