Skip to content

Commit 3edba95

Browse files
instruction selection for constants to account for duplicate tracking
1 parent e3e508f commit 3edba95

File tree

64 files changed

+963
-349
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+963
-349
lines changed

llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,13 @@ Register SPIRVGlobalRegistry::createConstInt(const ConstantInt *CI,
326326
SPIRVType *NewType =
327327
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
328328
MachineInstrBuilder MIB;
329-
if (!CI->isZero() || !ZeroAsNull) {
329+
if (BitWidth == 1) {
330+
MIB = MIRBuilder
331+
.buildInstr(CI->isZero() ? SPIRV::OpConstantFalse
332+
: SPIRV::OpConstantTrue)
333+
.addDef(Res)
334+
.addUse(getSPIRVTypeID(SpvType));
335+
} else if (!CI->isZero() || !ZeroAsNull) {
330336
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
331337
.addDef(Res)
332338
.addUse(getSPIRVTypeID(SpvType));
@@ -360,8 +366,9 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
360366

361367
unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
362368
LLT LLTy = LLT::scalar(BitWidth);
363-
Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
364-
MF.getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
369+
MachineRegisterInfo &MRI = MF.getRegInfo();
370+
Res = MRI.createGenericVirtualRegister(LLTy);
371+
MRI.setRegClass(Res, &SPIRV::iIDRegClass);
365372
assignTypeToVReg(Ty, Res, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
366373
EmitIR);
367374

llvm/lib/Target/SPIRV/SPIRVInstrInfo.td

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -216,42 +216,43 @@ def OpTypeCooperativeMatrixKHR: Op<4456, (outs TYPE:$res),
216216

217217
// 3.42.7 Constant-Creation Instructions
218218

219-
def imm_to_i32 : SDNodeXForm<imm, [{
220-
return CurDAG->getTargetConstant(
221-
N->getValueAP().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
222-
}]>;
219+
//def imm_to_i32 : SDNodeXForm<imm, [{
220+
//return CurDAG->getTargetConstant(
221+
// N->getValueAP().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
222+
//}]>;
223223

224-
def fimm_to_i64 : SDNodeXForm<imm, [{
225-
return CurDAG->getTargetConstant(
226-
N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
227-
}]>;
224+
//def fimm_to_i64 : SDNodeXForm<imm, [{
225+
//return CurDAG->getTargetConstant(
226+
// N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
227+
//}]>;
228228

229-
def gi_bitcast_fimm_to_i64 : GICustomOperandRenderer<"renderFImm64">,
230-
GISDNodeXFormEquiv<fimm_to_i64>;
229+
//def gi_bitcast_fimm_to_i64 : GICustomOperandRenderer<"renderFImm64">,
230+
// GISDNodeXFormEquiv<fimm_to_i64>;
231231

232-
def gi_bitcast_imm_to_i32 : GICustomOperandRenderer<"renderImm32">,
233-
GISDNodeXFormEquiv<imm_to_i32>;
232+
//def gi_bitcast_imm_to_i32 : GICustomOperandRenderer<"renderImm32">,
233+
// GISDNodeXFormEquiv<imm_to_i32>;
234234

235-
def PseudoConstI: IntImmLeaf<i64, [{ return Imm.getBitWidth() <= 32; }], imm_to_i32>;
236-
def PseudoConstF: FPImmLeaf<f64, [{ return true; }], fimm_to_i64>;
237-
def ConstPseudoTrue: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 1; }]>;
238-
def ConstPseudoFalse: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 0; }]>;
239-
def ConstPseudoNull: IntImmLeaf<i64, [{ return Imm.isZero(); }]>;
235+
//def PseudoConstI: IntImmLeaf<i64, [{ return Imm.getBitWidth() <= 32; }], imm_to_i32>;
236+
//def PseudoConstF: FPImmLeaf<f64, [{ return true; }], fimm_to_i64>;
237+
//def ConstPseudoNull: IntImmLeaf<i64, [{ return Imm.isZero(); }]>;
240238

241239
multiclass IntFPImm<bits<16> opCode, string name> {
242240
def I: Op<opCode, (outs iID:$dst), (ins TYPE:$type, iID:$src, variable_ops),
243-
"$dst = "#name#" $type", [(set iID:$dst, (assigntype PseudoConstI:$src, TYPE:$type))]>;
241+
"$dst = "#name#" $type">;
242+
//, [(set iID:$dst, (assigntype PseudoConstI:$src, TYPE:$type))]
244243
def F: Op<opCode, (outs fID:$dst), (ins TYPE:$type, fID:$src, variable_ops),
245-
"$dst = "#name#" $type", [(set fID:$dst, (assigntype PseudoConstF:$src, TYPE:$type))]>;
244+
"$dst = "#name#" $type">;
245+
//, [(set fID:$dst, (assigntype PseudoConstF:$src, TYPE:$type))]
246246
}
247+
defm OpConstant: IntFPImm<43, "OpConstant">;
247248

249+
def ConstPseudoTrue: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 1; }]>;
250+
def ConstPseudoFalse: IntImmLeaf<i64, [{ return Imm.getBitWidth() == 1 && Imm.getZExtValue() == 0; }]>;
248251
def OpConstantTrue: Op<41, (outs iID:$dst), (ins TYPE:$src_ty), "$dst = OpConstantTrue $src_ty",
249252
[(set iID:$dst, (assigntype ConstPseudoTrue, TYPE:$src_ty))]>;
250253
def OpConstantFalse: Op<42, (outs iID:$dst), (ins TYPE:$src_ty), "$dst = OpConstantFalse $src_ty",
251254
[(set iID:$dst, (assigntype ConstPseudoFalse, TYPE:$src_ty))]>;
252255

253-
defm OpConstant: IntFPImm<43, "OpConstant">;
254-
255256
def OpConstantComposite: Op<44, (outs ID:$res), (ins TYPE:$type, variable_ops),
256257
"$res = OpConstantComposite $type">;
257258
def OpConstantCompositeContinuedINTEL: Op<6091, (outs), (ins variable_ops),

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,12 @@ class SPIRVInstructionSelector : public InstructionSelector {
221221
bool selectWaveReduceSum(Register ResVReg, const SPIRVType *ResType,
222222
MachineInstr &I) const;
223223

224-
void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
225-
int OpIdx) const;
226-
void renderFImm64(MachineInstrBuilder &MIB, const MachineInstr &I,
227-
int OpIdx) const;
224+
//void renderImm32(MachineInstrBuilder &MIB, const MachineInstr &I,
225+
// int OpIdx) const;
226+
//void renderFImm64(MachineInstrBuilder &MIB, const MachineInstr &I,
227+
// int OpIdx) const;
228228

229-
bool selectConst(Register ResVReg, const SPIRVType *ResType, const APInt &Imm,
229+
bool selectConst(Register ResVReg, const SPIRVType *ResType,
230230
MachineInstr &I) const;
231231

232232
bool selectSelect(Register ResVReg, const SPIRVType *ResType, MachineInstr &I,
@@ -393,7 +393,8 @@ void SPIRVInstructionSelector::resetVRegsType(MachineFunction &MF) {
393393
}
394394
for (const auto &MBB : MF) {
395395
for (const auto &MI : MBB) {
396-
//GR.invalidateMachineInstr(&I);
396+
if (isPreISelGenericOpcode(MI.getOpcode()))
397+
GR.erase(&MI);
397398
if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
398399
continue;
399400

@@ -498,7 +499,9 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
498499
Register DstReg = I.getOperand(0).getReg();
499500
Register SrcReg = I.getOperand(1).getReg();
500501
auto *Def = MRI->getVRegDef(SrcReg);
501-
if (isTypeFoldingSupported(Def->getOpcode())) {
502+
if (isTypeFoldingSupported(Def->getOpcode()) &&
503+
Def->getOpcode() != TargetOpcode::G_CONSTANT &&
504+
Def->getOpcode() != TargetOpcode::G_FCONSTANT) {
502505
bool Res = selectImpl(I, *CoverageInfo);
503506
LLVM_DEBUG({
504507
if (!Res && Def->getOpcode() != TargetOpcode::G_CONSTANT) {
@@ -560,6 +563,7 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
560563
static bool mayApplyGenericSelection(unsigned Opcode) {
561564
switch (Opcode) {
562565
case TargetOpcode::G_CONSTANT:
566+
case TargetOpcode::G_FCONSTANT:
563567
return false;
564568
case TargetOpcode::G_SADDO:
565569
case TargetOpcode::G_SSUBO:
@@ -589,8 +593,8 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
589593
return selectImpl(I, *CoverageInfo);
590594
switch (Opcode) {
591595
case TargetOpcode::G_CONSTANT:
592-
return selectConst(ResVReg, ResType, I.getOperand(1).getCImm()->getValue(),
593-
I);
596+
case TargetOpcode::G_FCONSTANT:
597+
return selectConst(ResVReg, ResType, I);
594598
case TargetOpcode::G_GLOBAL_VALUE:
595599
return selectGlobalValue(ResVReg, I);
596600
case TargetOpcode::G_IMPLICIT_DEF:
@@ -2460,7 +2464,7 @@ bool SPIRVInstructionSelector::selectICmp(Register ResVReg,
24602464
CmpOpc = getICmpOpcode(Pred);
24612465
return selectCmp(ResVReg, ResType, CmpOpc, I);
24622466
}
2463-
2467+
/*
24642468
void SPIRVInstructionSelector::renderFImm64(MachineInstrBuilder &MIB,
24652469
const MachineInstr &I,
24662470
int OpIdx) const {
@@ -2477,7 +2481,7 @@ void SPIRVInstructionSelector::renderImm32(MachineInstrBuilder &MIB,
24772481
"Expected G_CONSTANT");
24782482
addNumImm(I.getOperand(1).getCImm()->getValue(), MIB);
24792483
}
2480-
2484+
*/
24812485
std::pair<Register, bool>
24822486
SPIRVInstructionSelector::buildI32Constant(uint32_t Val, MachineInstr &I,
24832487
const SPIRVType *ResType) const {
@@ -2711,37 +2715,24 @@ bool SPIRVInstructionSelector::selectTrunc(Register ResVReg,
27112715

27122716
bool SPIRVInstructionSelector::selectConst(Register ResVReg,
27132717
const SPIRVType *ResType,
2714-
const APInt &Imm,
27152718
MachineInstr &I) const {
2716-
unsigned TyOpcode = ResType->getOpcode();
2717-
assert(TyOpcode != SPIRV::OpTypePointer || Imm.isZero());
2718-
MachineBasicBlock &BB = *I.getParent();
2719-
if ((TyOpcode == SPIRV::OpTypePointer || TyOpcode == SPIRV::OpTypeEvent) &&
2720-
Imm.isZero())
2721-
return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
2722-
.addDef(ResVReg)
2723-
.addUse(GR.getSPIRVTypeID(ResType))
2724-
.constrainAllUses(TII, TRI, RBI);
2725-
if (TyOpcode == SPIRV::OpTypeInt) {
2726-
assert(Imm.getBitWidth() <= 64 && "Unsupported integer width!");
2727-
const ConstantInt *CI =
2728-
ConstantInt::get(const_cast<IntegerType *>(cast<IntegerType>(
2729-
GR.getTypeForSPIRVType(ResType))),
2730-
Imm.getZExtValue());
2731-
const MachineInstr *ConstMI = GR.findMI(CI, GR.CurMF);
2732-
Register Reg =
2733-
(ConstMI && ConstMI != &I)
2734-
? ConstMI->getOperand(0).getReg()
2735-
: GR.createConstInt(CI, I, ResType, TII, STI.isOpenCLEnv());
2736-
return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
2737-
}
2738-
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
2739-
.addDef(ResVReg)
2740-
.addUse(GR.getSPIRVTypeID(ResType));
2741-
// <=32-bit integers should be caught by the sdag pattern.
2742-
assert(Imm.getBitWidth() > 32);
2743-
addNumImm(Imm, MIB);
2744-
return MIB.constrainAllUses(TII, TRI, RBI);
2719+
unsigned Opcode = I.getOpcode();
2720+
unsigned TpOpcode = ResType->getOpcode();
2721+
Register Reg;
2722+
if (TpOpcode == SPIRV::OpTypePointer || TpOpcode == SPIRV::OpTypeEvent) {
2723+
assert(Opcode == TargetOpcode::G_CONSTANT &&
2724+
I.getOperand(1).getCImm()->isZero());
2725+
MachineBasicBlock &DepMBB = I.getMF()->front();
2726+
MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
2727+
Reg = GR.getOrCreateConstNullPtr(MIRBuilder, ResType);
2728+
} else if (Opcode == TargetOpcode::G_FCONSTANT) {
2729+
Reg = GR.getOrCreateConstFP(I.getOperand(1).getFPImm()->getValue(), I,
2730+
ResType, TII, STI.isOpenCLEnv());
2731+
} else {
2732+
Reg = GR.getOrCreateConstInt(I.getOperand(1).getCImm()->getZExtValue(), I,
2733+
ResType, TII, STI.isOpenCLEnv());
2734+
}
2735+
return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
27452736
}
27462737

27472738
bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,

llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
146146

147147
for (auto Opc : getTypeFoldingSupportedOpcodes())
148148
getActionDefinitionsBuilder(Opc).custom();
149+
//getActionDefinitionsBuilder(TargetOpcode::G_CONSTANT).custom();
150+
//getActionDefinitionsBuilder(TargetOpcode::G_FCONSTANT).custom();
149151

150152
getActionDefinitionsBuilder(G_GLOBAL_VALUE).alwaysLegal();
151153

@@ -353,8 +355,7 @@ bool SPIRVLegalizerInfo::legalizeCustom(
353355
LostDebugLocObserver &LocObserver) const {
354356
auto Opc = MI.getOpcode();
355357
MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
356-
if (!isTypeFoldingSupported(Opc)) {
357-
assert(Opc == TargetOpcode::G_ICMP);
358+
if (Opc == TargetOpcode::G_ICMP) {
358359
assert(GR->getSPIRVTypeForVReg(MI.getOperand(0).getReg()));
359360
auto &Op0 = MI.getOperand(2);
360361
auto &Op1 = MI.getOperand(3);

llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ extern void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
4747
SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
4848
MachineRegisterInfo &MRI);
4949
extern void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
50-
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR);
50+
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR,
51+
SPIRVType *KnownResType);
5152
} // namespace llvm
5253

5354
static bool mayBeInserted(unsigned Opcode) {
5455
switch (Opcode) {
56+
// case TargetOpcode::G_CONSTANT:
57+
// case TargetOpcode::G_FCONSTANT:
5558
case TargetOpcode::G_SMAX:
5659
case TargetOpcode::G_UMAX:
5760
case TargetOpcode::G_SMIN:
@@ -102,20 +105,32 @@ static void processNewInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
102105
Register ResVReg = I.getOperand(0).getReg();
103106
// Check if the register defined by the instruction is newly generated
104107
// or already processed
105-
if (MRI.getRegClassOrNull(ResVReg))
108+
/*if (MRI.getRegClassOrNull(ResVReg)) {
109+
if (isTypeFoldingSupported(Opcode)) {
110+
insertAssignInstr(ResVReg, nullptr, ResVType, GR, MIB, MRI);
111+
processInstr(I, MIB, MRI, GR, GR->getSPIRVTypeForVReg(ResVReg));
112+
}
106113
continue;
107-
assert(GR->getSPIRVTypeForVReg(ResVReg) == nullptr);
114+
}*/
108115
// Check if we have type defined for operands of the new instruction
109-
SPIRVType *ResVType = GR->getSPIRVTypeForVReg(I.getOperand(1).getReg());
116+
bool IsKnownReg = MRI.getRegClassOrNull(ResVReg);
117+
SPIRVType *ResVType = GR->getSPIRVTypeForVReg(
118+
IsKnownReg ? ResVReg : I.getOperand(1).getReg());
110119
if (!ResVType)
111120
continue;
112121
// Set type & class
113-
setRegClassType(ResVReg, ResVType, GR, &MRI, *GR->CurMF, true);
122+
if (!IsKnownReg)
123+
setRegClassType(ResVReg, ResVType, GR, &MRI, *GR->CurMF, true);
114124
// If this is a simple operation that is to be reduced by TableGen
115125
// definition we must apply some of pre-legalizer rules here
116126
if (isTypeFoldingSupported(Opcode)) {
127+
processInstr(I, MIB, MRI, GR, GR->getSPIRVTypeForVReg(ResVReg));
128+
if (IsKnownReg && MRI.hasOneUse(ResVReg)) {
129+
MachineInstr &UseMI = *MRI.use_instr_begin(ResVReg);
130+
if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
131+
continue;
132+
}
117133
insertAssignInstr(ResVReg, nullptr, ResVType, GR, MIB, MRI);
118-
processInstr(I, MIB, MRI, GR);
119134
}
120135
}
121136
}

llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,13 +484,18 @@ void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
484484
}
485485

486486
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
487-
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR) {
487+
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR,
488+
SPIRVType *KnownResType) {
488489
MIB.setInsertPt(*MI.getParent(), MI.getIterator());
489490
for (auto &Op : MI.operands()) {
490491
if (!Op.isReg() || Op.isDef())
491492
continue;
492493
Register OpReg = Op.getReg();
493494
SPIRVType *SpvType = GR->getSPIRVTypeForVReg(OpReg);
495+
if (!SpvType && KnownResType) {
496+
SpvType = KnownResType;
497+
GR->assignSPIRVTypeToVReg(KnownResType, OpReg, *MI.getMF());
498+
}
494499
assert(SpvType);
495500
if (!MRI.getRegClassOrNull(OpReg))
496501
MRI.setRegClass(OpReg, GR->getRegClass(SpvType));
@@ -720,7 +725,7 @@ static void processInstrsWithTypeFolding(MachineFunction &MF,
720725
for (MachineBasicBlock &MBB : MF)
721726
for (MachineInstr &MI : MBB)
722727
if (isTypeFoldingSupported(MI.getOpcode()))
723-
processInstr(MI, MIB, MRI, GR);
728+
processInstr(MI, MIB, MRI, GR, nullptr);
724729
}
725730

726731
static Register

llvm/test/CodeGen/SPIRV/AtomicCompareExchange.ll

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
1+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
23

3-
; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0
4-
; CHECK-SPIRV-DAG: %[[#MemScope_CrossDevice:]] = OpConstant %[[#Int]] 0
5-
; CHECK-SPIRV-DAG: %[[#MemSemEqual_SeqCst:]] = OpConstant %[[#Int]] 16
6-
; CHECK-SPIRV-DAG: %[[#MemSemUnequal_Acquire:]] = OpConstant %[[#Int]] 2
7-
; CHECK-SPIRV-DAG: %[[#Constant_456:]] = OpConstant %[[#Int]] 456
8-
; CHECK-SPIRV-DAG: %[[#Constant_128:]] = OpConstant %[[#Int]] 128
4+
; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0
5+
; CHECK-SPIRV-DAG: %[[#MemScope_CrossDevice:]] = OpConstantNull %[[#Int]]
6+
; CHECK-SPIRV-DAG: %[[#MemSemEqual_SeqCst:]] = OpConstant %[[#Int]] 16{{$}}
7+
; CHECK-SPIRV-DAG: %[[#MemSemUnequal_Acquire:]] = OpConstant %[[#Int]] 2{{$}}
8+
; CHECK-SPIRV-DAG: %[[#Constant_456:]] = OpConstant %[[#Int]] 456{{$}}
9+
; CHECK-SPIRV-DAG: %[[#Constant_128:]] = OpConstant %[[#Int]] 128{{$}}
910
; CHECK-SPIRV-DAG: %[[#Bool:]] = OpTypeBool
1011
; CHECK-SPIRV-DAG: %[[#Struct:]] = OpTypeStruct %[[#Int]] %[[#Bool]]
1112
; CHECK-SPIRV-DAG: %[[#UndefStruct:]] = OpUndef %[[#Struct]]

0 commit comments

Comments
 (0)