Skip to content

Commit 8d8996d

Browse files
[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.
1 parent 62d6fa8 commit 8d8996d

File tree

9 files changed

+389
-88
lines changed

9 files changed

+389
-88
lines changed

llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ class SPIRVAsmPrinter : public AsmPrinter {
7878
void outputExecutionMode(const Module &M);
7979
void outputAnnotations(const Module &M);
8080
void outputModuleSections();
81+
bool isHidden() {
82+
return MF->getFunction()
83+
.getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME)
84+
.isValid();
85+
}
8186

8287
void emitInstruction(const MachineInstr *MI) override;
8388
void emitFunctionEntryLabel() override {}
@@ -131,7 +136,7 @@ void SPIRVAsmPrinter::emitFunctionHeader() {
131136
TII = ST->getInstrInfo();
132137
const Function &F = MF->getFunction();
133138

134-
if (isVerbose()) {
139+
if (isVerbose() && !isHidden()) {
135140
OutStreamer->getCommentOS()
136141
<< "-- Begin function "
137142
<< GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n';
@@ -149,11 +154,18 @@ void SPIRVAsmPrinter::outputOpFunctionEnd() {
149154

150155
// Emit OpFunctionEnd at the end of MF and clear BBNumToRegMap.
151156
void SPIRVAsmPrinter::emitFunctionBodyEnd() {
157+
// Do not emit anything if it's an internal service function.
158+
if (isHidden())
159+
return;
152160
outputOpFunctionEnd();
153161
MAI->BBNumToRegMap.clear();
154162
}
155163

156164
void SPIRVAsmPrinter::emitOpLabel(const MachineBasicBlock &MBB) {
165+
// Do not emit anything if it's an internal service function.
166+
if (isHidden())
167+
return;
168+
157169
MCInst LabelInst;
158170
LabelInst.setOpcode(SPIRV::OpLabel);
159171
LabelInst.addOperand(MCOperand::createReg(MAI->getOrCreateMBBRegister(MBB)));
@@ -162,7 +174,9 @@ void SPIRVAsmPrinter::emitOpLabel(const MachineBasicBlock &MBB) {
162174
}
163175

164176
void SPIRVAsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
165-
assert(!MBB.empty() && "MBB is empty!");
177+
// Do not emit anything if it's an internal service function.
178+
if (MBB.empty())
179+
return;
166180

167181
// If it's the first MBB in MF, it has OpFunction and OpFunctionParameter, so
168182
// OpLabel should be output after them.

llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ bool SPIRVCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
3636
const Value *Val, ArrayRef<Register> VRegs,
3737
FunctionLoweringInfo &FLI,
3838
Register SwiftErrorVReg) const {
39+
// Ignore if called from the internal service function
40+
if (MIRBuilder.getMF()
41+
.getFunction()
42+
.getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME)
43+
.isValid())
44+
return true;
45+
3946
// Maybe run postponed production of types for function pointers
4047
if (IndirectCalls.size() > 0) {
4148
produceIndirectPtrTypes(MIRBuilder);
@@ -280,6 +287,10 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
280287
const Function &F,
281288
ArrayRef<ArrayRef<Register>> VRegs,
282289
FunctionLoweringInfo &FLI) const {
290+
// Discard the internal service function
291+
if (F.getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME).isValid())
292+
return true;
293+
283294
assert(GR && "Must initialize the SPIRV type registry before lowering args.");
284295
GR->setCurrentFunc(MIRBuilder.getMF());
285296

@@ -576,6 +587,16 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
576587
lowerFormalArguments(FirstBlockBuilder, *CF, VRegArgs, FuncInfo);
577588
}
578589

590+
// Ignore the call if it's called from the internal service function
591+
if (MIRBuilder.getMF()
592+
.getFunction()
593+
.getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME)
594+
.isValid()) {
595+
// insert a no-op
596+
MIRBuilder.buildTrap();
597+
return true;
598+
}
599+
579600
unsigned CallOp;
580601
if (Info.CB->isIndirectCall()) {
581602
if (!ST->canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))

0 commit comments

Comments
 (0)