Skip to content

Commit aa2297e

Browse files
harden implementation of the duplicate tracker; fix generation of global variables
1 parent 2506f5a commit aa2297e

File tree

3 files changed

+25
-40
lines changed

3 files changed

+25
-40
lines changed

llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,9 +536,8 @@ static Register buildBuiltinVariableLoad(
536536
/// SPIRVType in ASSIGN_TYPE, otherwise create it from \p Ty. Defined in
537537
/// SPIRVPreLegalizer.cpp.
538538
extern void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
539-
SPIRVGlobalRegistry *GR,
540-
MachineIRBuilder &MIB,
541-
MachineRegisterInfo &MRI);
539+
SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
540+
MachineRegisterInfo &MRI);
542541

543542
// TODO: Move to TableGen.
544543
static SPIRV::MemorySemantics::MemorySemantics

llvm/lib/Target/SPIRV/SPIRVIRMapping.h

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===-- SPIRVDuplicatesTracker.h - SPIR-V Duplicates Tracker ----*- C++ -*-===//
1+
//===------------ SPIRVMapping.h - SPIR-V Duplicates Tracker ----*- C++ -*-===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -26,28 +26,6 @@
2626

2727
namespace llvm {
2828
namespace SPIRV {
29-
/*
30-
inline size_t to_hash(const MachineInstr *MI,
31-
std::unordered_set<const MachineInstr *> &Visited) {
32-
if (!MI || !Visited.insert(MI).second)
33-
return 0;
34-
const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
35-
SmallVector<size_t, 16> Codes{MI->getOpcode()};
36-
size_t H;
37-
for (unsigned I = MI->getNumDefs(); I < MI->getNumOperands(); ++I) {
38-
const MachineOperand &MO = MI->getOperand(I);
39-
H = MO.isReg() ? to_hash(getDef(MO, &MRI), Visited)
40-
: size_t(llvm::hash_value(MO));
41-
Codes.push_back(H);
42-
}
43-
return llvm::hash_combine(Codes.begin(), Codes.end());
44-
}
45-
46-
inline size_t to_hash(const MachineInstr *MI) {
47-
std::unordered_set<const MachineInstr *> Visited;
48-
return to_hash(MI, Visited);
49-
}
50-
*/
5129

5230
inline size_t to_hash(const MachineInstr *MI) {
5331
hash_code H = llvm::hash_combine(MI->getOpcode(), MI->getNumOperands());
@@ -63,10 +41,10 @@ inline size_t to_hash(const MachineInstr *MI) {
6341
return H;
6442
}
6543

66-
using MIHandle = std::pair<const MachineInstr *, size_t>;
44+
using MIHandle = std::tuple<const MachineInstr *, Register, size_t>;
6745

6846
inline MIHandle getMIKey(const MachineInstr *MI) {
69-
return std::make_pair(MI, SPIRV::to_hash(MI));
47+
return std::make_tuple(MI, MI->getOperand(0).getReg(), SPIRV::to_hash(MI));
7048
}
7149

7250
using IRHandle = std::tuple<const void *, unsigned, unsigned>;
@@ -200,10 +178,8 @@ class SPIRVIRMapping {
200178
SPIRV::MIHandle MIKey = SPIRV::getMIKey(MI);
201179
auto It1 = Vregs.try_emplace(HandleMF, MIKey);
202180
if (!It1.second) {
203-
// there is an expired record
204-
auto [ExistMI, _] = It1.first->second;
205-
// invalidate the record
206-
Defs.erase(ExistMI);
181+
// there is an expired record that we need to invalidate
182+
Defs.erase(std::get<0>(It1.first->second));
207183
// update the record
208184
It1.first->second = MIKey;
209185
}
@@ -225,13 +201,14 @@ class SPIRVIRMapping {
225201
auto It = Vregs.find(HandleMF);
226202
if (It == Vregs.end())
227203
return nullptr;
228-
auto [MI, Hash] = It->second;
229-
assert(SPIRV::to_hash(MI) == Hash);
230-
assert(Defs.find(MI) != Defs.end() && Defs.find(MI)->second == HandleMF);
231-
/*if (SPIRV::to_hash(MI) != Hash) {
204+
auto [MI, Reg, Hash] = It->second;
205+
const MachineInstr *Def = MF->getRegInfo().getVRegDef(Reg);
206+
if (!Def || Def != MI || SPIRV::to_hash(MI) != Hash) {
207+
// there is an expired record that we need to invalidate
232208
erase(MI);
233209
return nullptr;
234-
}*/
210+
}
211+
assert(Defs.find(MI) != Defs.end() && Defs.find(MI)->second == HandleMF);
235212
return MI;
236213
}
237214
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF) {

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,8 @@ bool SPIRVInstructionSelector::selectUnOp(Register ResVReg,
10411041
for (MachineRegisterInfo::def_instr_iterator DefIt =
10421042
MRI->def_instr_begin(SrcReg);
10431043
DefIt != MRI->def_instr_end(); DefIt = std::next(DefIt)) {
1044-
if ((*DefIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
1044+
if ((*DefIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1045+
(*DefIt).getOpcode() == SPIRV::OpVariable) {
10451046
IsGV = true;
10461047
break;
10471048
}
@@ -2727,7 +2728,6 @@ bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,
27272728
.constrainAllUses(TII, TRI, RBI);
27282729
}
27292730

2730-
27312731
bool SPIRVInstructionSelector::selectInsertVal(Register ResVReg,
27322732
const SPIRVType *ResType,
27332733
MachineInstr &I) const {
@@ -2886,7 +2886,16 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
28862886
? MRI->getVRegDef(I.getOperand(2).getReg())
28872887
: nullptr;
28882888
assert(MI);
2889-
return selectGlobalValue(MI->getOperand(0).getReg(), *MI, Init);
2889+
Register GVarVReg = MI->getOperand(0).getReg();
2890+
bool Res = selectGlobalValue(GVarVReg, *MI, Init);
2891+
// We violate SSA form by inserting OpVariable having a gMIR instruction
2892+
// %vreg = G_GLOBAL_VALUE @gvar
2893+
// We need to fix this erasing the duplicated definition.
2894+
if (MI->getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
2895+
GR.invalidateMachineInstr(MI);
2896+
MI->removeFromParent();
2897+
}
2898+
return Res;
28902899
}
28912900
case Intrinsic::spv_undef: {
28922901
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))

0 commit comments

Comments
 (0)