Skip to content

[SPIR-V] Overhaul module analysis to improve translation speed and simplify the underlying logics #120415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion llvm/lib/Target/SPIRV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ add_llvm_target(SPIRVCodeGen
SPIRVCallLowering.cpp
SPIRVInlineAsmLowering.cpp
SPIRVCommandLine.cpp
SPIRVDuplicatesTracker.cpp
SPIRVEmitIntrinsics.cpp
SPIRVGlobalRegistry.cpp
SPIRVInstrInfo.cpp
Expand Down
13 changes: 6 additions & 7 deletions llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) {
}

void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) {
for (MachineInstr *MI : MAI->getMSInstrs(MSType))
for (const MachineInstr *MI : MAI->getMSInstrs(MSType))
outputInstruction(MI);
}

Expand Down Expand Up @@ -326,7 +326,7 @@ void SPIRVAsmPrinter::outputOpMemoryModel() {
void SPIRVAsmPrinter::outputEntryPoints() {
// Find all OpVariable IDs with required StorageClass.
DenseSet<Register> InterfaceIDs;
for (MachineInstr *MI : MAI->GlobalVarList) {
for (const MachineInstr *MI : MAI->GlobalVarList) {
assert(MI->getOpcode() == SPIRV::OpVariable);
auto SC = static_cast<SPIRV::StorageClass::StorageClass>(
MI->getOperand(2).getImm());
Expand All @@ -336,14 +336,14 @@ void SPIRVAsmPrinter::outputEntryPoints() {
// declaring all global variables referenced by the entry point call tree.
if (ST->isAtLeastSPIRVVer(VersionTuple(1, 4)) ||
SC == SPIRV::StorageClass::Input || SC == SPIRV::StorageClass::Output) {
MachineFunction *MF = MI->getMF();
const MachineFunction *MF = MI->getMF();
Register Reg = MAI->getRegisterAlias(MF, MI->getOperand(0).getReg());
InterfaceIDs.insert(Reg);
}
}

// Output OpEntryPoints adding interface args to all of them.
for (MachineInstr *MI : MAI->getMSInstrs(SPIRV::MB_EntryPoints)) {
for (const MachineInstr *MI : MAI->getMSInstrs(SPIRV::MB_EntryPoints)) {
SPIRVMCInstLower MCInstLowering;
MCInst TmpInst;
MCInstLowering.lower(MI, TmpInst, MAI);
Expand Down Expand Up @@ -381,9 +381,8 @@ void SPIRVAsmPrinter::outputGlobalRequirements() {

void SPIRVAsmPrinter::outputExtFuncDecls() {
// Insert OpFunctionEnd after each declaration.
SmallVectorImpl<MachineInstr *>::iterator
I = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).begin(),
E = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).end();
auto I = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).begin(),
E = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).end();
for (; I != E; ++I) {
outputInstruction(*I);
if ((I + 1) == E || (*(I + 1))->getOpcode() == SPIRV::OpFunction)
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
.addImm(FuncControl)
.addUse(GR->getSPIRVTypeID(FuncTy));
GR->recordFunctionDefinition(&F, &MB.getInstr()->getOperand(0));
GR->addGlobalObject(&F, &MIRBuilder.getMF(), FuncVReg);

// Add OpFunctionParameter instructions
int i = 0;
Expand All @@ -431,6 +432,7 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
.addUse(GR->getSPIRVTypeID(ArgTypeVRegs[i]));
if (F.isDeclaration())
GR->add(&Arg, &MIRBuilder.getMF(), ArgReg);
GR->addGlobalObject(&Arg, &MIRBuilder.getMF(), ArgReg);
i++;
}
// Name the function.
Expand Down
136 changes: 0 additions & 136 deletions llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp

This file was deleted.

16 changes: 0 additions & 16 deletions llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,23 +211,7 @@ class SPIRVGeneralDuplicatesTracker {
SPIRVDuplicatesTracker<MachineInstr> MT;
SPIRVDuplicatesTracker<SPIRV::SpecialTypeDescriptor> ST;

// NOTE: using MOs instead of regs to get rid of MF dependency to be able
// to use flat data structure.
// NOTE: replacing DenseMap with MapVector doesn't affect overall correctness
// but makes LITs more stable, should prefer DenseMap still due to
// significant perf difference.
using SPIRVReg2EntryTy =
MapVector<MachineOperand *, SPIRV::DTSortableEntry *>;

template <typename T>
void prebuildReg2Entry(SPIRVDuplicatesTracker<T> &DT,
SPIRVReg2EntryTy &Reg2Entry,
const SPIRVInstrInfo *TII);

public:
void buildDepsGraph(std::vector<SPIRV::DTSortableEntry *> &Graph,
const SPIRVInstrInfo *TII, MachineModuleInfo *MMI);

void add(const Type *Ty, const MachineFunction *MF, Register R) {
TT.add(unifyPtrType(Ty), MF, R);
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
}
Reg = MIB->getOperand(0).getReg();
DT.add(GVar, &MIRBuilder.getMF(), Reg);
addGlobalObject(GVar, &MIRBuilder.getMF(), Reg);

// Set to Reg the same type as ResVReg has.
auto MRI = MIRBuilder.getMRI();
Expand Down
17 changes: 11 additions & 6 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ class SPIRVGlobalRegistry {
// Intrinsic::spv_assign_ptr_type instructions.
DenseMap<Value *, CallInst *> AssignPtrTypeInstr;

// Maps OpVariable and OpFunction-related v-regs to its LLVM IR definition.
DenseMap<std::pair<const MachineFunction *, Register>, const Value *> Reg2GO;

// Add a new OpTypeXXX instruction without checking for duplicates.
SPIRVType *createSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AQ =
Expand Down Expand Up @@ -151,15 +154,17 @@ class SPIRVGlobalRegistry {
return DT.find(F, MF);
}

void buildDepsGraph(std::vector<SPIRV::DTSortableEntry *> &Graph,
const SPIRVInstrInfo *TII,
MachineModuleInfo *MMI = nullptr) {
DT.buildDepsGraph(Graph, TII, MMI);
}

void setBound(unsigned V) { Bound = V; }
unsigned getBound() { return Bound; }

void addGlobalObject(const Value *V, const MachineFunction *MF, Register R) {
Reg2GO[std::make_pair(MF, R)] = V;
}
const Value *getGlobalObject(const MachineFunction *MF, Register R) {
auto It = Reg2GO.find(std::make_pair(MF, R));
return It == Reg2GO.end() ? nullptr : It->second;
}

// Add a record to the map of function return pointer types.
void addReturnType(const Function *ArgF, TypedPointerType *DerivedTy) {
FunResPointerTypes[ArgF] = DerivedTy;
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ bool SPIRVInstrInfo::isConstantInstr(const MachineInstr &MI) const {
}
}

bool SPIRVInstrInfo::isSpecConstantInstr(const MachineInstr &MI) const {
switch (MI.getOpcode()) {
case SPIRV::OpSpecConstantTrue:
case SPIRV::OpSpecConstantFalse:
case SPIRV::OpSpecConstant:
case SPIRV::OpSpecConstantComposite:
case SPIRV::OpSpecConstantOp:
return true;
default:
return false;
}
}

bool SPIRVInstrInfo::isInlineAsmDefInstr(const MachineInstr &MI) const {
switch (MI.getOpcode()) {
case SPIRV::OpAsmTargetINTEL:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SPIRV/SPIRVInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class SPIRVInstrInfo : public SPIRVGenInstrInfo {
const SPIRVRegisterInfo &getRegisterInfo() const { return RI; }
bool isHeaderInstr(const MachineInstr &MI) const;
bool isConstantInstr(const MachineInstr &MI) const;
bool isSpecConstantInstr(const MachineInstr &MI) const;
bool isInlineAsmDefInstr(const MachineInstr &MI) const;
bool isTypeDeclInstr(const MachineInstr &MI) const;
bool isDecorationInstr(const MachineInstr &MI) const;
Expand Down
20 changes: 14 additions & 6 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,7 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
Constant::getNullValue(LLVMArrTy));
Register VarReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
GR.add(GV, GR.CurMF, VarReg);
GR.addGlobalObject(GV, GR.CurMF, VarReg);

Result &=
BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpVariable))
Expand Down Expand Up @@ -3509,18 +3510,25 @@ bool SPIRVInstructionSelector::selectGlobalValue(
// References to a function via function pointers generate virtual
// registers without a definition. We will resolve it later, during
// module analysis stage.
Register ResTypeReg = GR.getSPIRVTypeID(ResType);
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
Register FuncVReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
MRI->setRegClass(FuncVReg, &SPIRV::iIDRegClass);
MachineInstrBuilder MB =
Register FuncVReg =
MRI->createGenericVirtualRegister(GR.getRegType(ResType));
MRI->setRegClass(FuncVReg, &SPIRV::pIDRegClass);
MachineInstrBuilder MIB1 =
BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
.addDef(FuncVReg)
.addUse(ResTypeReg);
MachineInstrBuilder MIB2 =
BuildMI(BB, I, I.getDebugLoc(),
TII.get(SPIRV::OpConstantFunctionPointerINTEL))
.addDef(NewReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(ResTypeReg)
.addUse(FuncVReg);
// mapping the function pointer to the used Function
GR.recordFunctionPointer(&MB.getInstr()->getOperand(2), GVFun);
return MB.constrainAllUses(TII, TRI, RBI);
GR.recordFunctionPointer(&MIB2.getInstr()->getOperand(2), GVFun);
return MIB1.constrainAllUses(TII, TRI, RBI) &&
MIB2.constrainAllUses(TII, TRI, RBI);
}
return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
.addDef(NewReg)
Expand Down
Loading
Loading