Skip to content

Commit 0db8a75

Browse files
davidjwooigcbot
authored andcommitted
Initialize phis used as sample sources
Initialize to 0 any registers used to hold the result of phi instructions that are also used as a source for sample instructions.
1 parent abcc78b commit 0db8a75

File tree

3 files changed

+152
-9
lines changed

3 files changed

+152
-9
lines changed

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,9 @@ static bool DefReachUseWithinLevel(llvm::Value* def, const llvm::Instruction* us
273273
return false;
274274
}
275275

276-
bool EmitPass::IsNoMaskAllowed(SDAG& sdag)
276+
bool EmitPass::IsNoMaskAllowed(Instruction* inst)
277277
{
278-
if (auto* I = dyn_cast<LoadInst>(sdag.m_root))
278+
if (auto* I = dyn_cast<LoadInst>(inst))
279279
{
280280
if (IGC_IS_FLAG_ENABLED(UseVMaskPredicateForLoads) && shouldGenerateLSC(I))
281281
return true;
@@ -290,6 +290,15 @@ bool EmitPass::IsNoMaskAllowed(SDAG& sdag)
290290
return true;
291291
}
292292

293+
bool EmitPass::IsSubspanDestination(Instruction* inst)
294+
{
295+
return m_pattern->IsSubspanUse(inst) && IsNoMaskAllowed(inst) &&
296+
(!m_pattern->IsSourceOfSample(inst) ||
297+
(m_pattern->IsSourceOfSample(inst) && m_pCtx->getModule()->getNamedMetadata(NAMED_METADATA_COARSE_PHASE) != nullptr) ||
298+
(m_pattern->IsSourceOfSample(inst) && !m_pattern->NeedVMask()) ||
299+
(m_pattern->IsSourceOfSample(inst) && m_pattern->NeedVMask() && m_pattern->IsSourceOfSampleUnderCF(inst)));
300+
}
301+
293302
uint EmitPass::DecideInstanceAndSlice(const llvm::BasicBlock& blk, SDAG& sdag, bool& slicing)
294303
{
295304
m_encoder->SetSubSpanDestination(false);
@@ -317,11 +326,7 @@ uint EmitPass::DecideInstanceAndSlice(const llvm::BasicBlock& blk, SDAG& sdag, b
317326
m_destination = GetSymbol(sdag.m_root);
318327
numInstance = m_destination->GetNumberInstance();
319328

320-
if (m_pattern->IsSubspanUse(sdag.m_root) && IsNoMaskAllowed(sdag) &&
321-
(!m_pattern->IsSourceOfSample(sdag.m_root) ||
322-
(m_pattern->IsSourceOfSample(sdag.m_root) && m_pCtx->getModule()->getNamedMetadata(NAMED_METADATA_COARSE_PHASE) != nullptr) ||
323-
(m_pattern->IsSourceOfSample(sdag.m_root) && !m_pattern->NeedVMask()) ||
324-
(m_pattern->IsSourceOfSample(sdag.m_root) && m_pattern->NeedVMask() && m_pattern->IsSourceOfSampleUnderCF(sdag.m_root))))
329+
if (IsSubspanDestination(sdag.m_root))
325330
{
326331
m_encoder->SetSubSpanDestination(true);
327332
}
@@ -9627,6 +9632,75 @@ void EmitPass::EmitInlineAsm(llvm::CallInst* inst)
96279632
str << "/// End Inlined ASM" << endl << endl;
96289633
}
96299634

9635+
void EmitPass::EmitInitializePHI(llvm::PHINode* phi)
9636+
{
9637+
if (m_destination->IsUniform())
9638+
{
9639+
return;
9640+
}
9641+
if (m_deSSA && m_deSSA->getRootValue(phi) != nullptr)
9642+
{
9643+
// If this phi is not isolated, it can be safely initialized only if no
9644+
// other values it is coalesced with use NoMask on their destinations.
9645+
// NoMask could be used if the other value is:
9646+
// - uniform(handled above)
9647+
// - also a phi that is being initialized
9648+
// - emitted with m_SubSpanDestination set to true
9649+
{
9650+
SmallVector<Value*, 16> coalescedValues;
9651+
m_deSSA->getAllCoalescedValues(phi, coalescedValues);
9652+
for (auto val : coalescedValues)
9653+
{
9654+
if (val != phi &&
9655+
(isa<PHINode>(val) && m_pattern->IsSourceOfSample(val)) ||
9656+
(isa<Instruction>(val) && IsSubspanDestination(cast<Instruction>(val))))
9657+
{
9658+
return;
9659+
}
9660+
}
9661+
}
9662+
}
9663+
9664+
if (m_destination->GetType() == ISA_TYPE_BOOL)
9665+
{
9666+
CVariable* initializedTempVar = m_currShader->GetNewVariable(m_destination->GetNumberElement(), ISA_TYPE_UD, EALIGN_GRF, CName::NONE);
9667+
m_encoder->SetNoMask();
9668+
m_encoder->Copy(initializedTempVar, m_currShader->ImmToVariable(0, ISA_TYPE_UD));
9669+
m_encoder->Push();
9670+
9671+
m_encoder->Select(m_destination, initializedTempVar, m_currShader->ImmToVariable(0xFFFFFFFFULL, ISA_TYPE_UD), m_currShader->ImmToVariable(0, ISA_TYPE_UD));
9672+
m_encoder->Push();
9673+
9674+
CVariable* initializedFlag = m_currShader->GetNewVariable(m_destination);
9675+
VISA_Type type = GetTypeFromSize(m_destination->GetNumberElement() / BITS_PER_BYTE);
9676+
m_encoder->SetNoMask();
9677+
m_encoder->SetP(initializedFlag, m_currShader->ImmToVariable(0, type));
9678+
m_encoder->Push();
9679+
9680+
m_encoder->Cmp(EPREDICATE_EQ, initializedFlag, initializedTempVar, m_currShader->ImmToVariable(0xFFFFFFFFULL, ISA_TYPE_UD));
9681+
m_encoder->Push();
9682+
9683+
m_encoder->Copy(m_destination, initializedFlag);
9684+
m_encoder->Push();
9685+
}
9686+
else
9687+
{
9688+
VISA_Type unsignedType = GetUnsignedIntegerType(m_destination->GetType());
9689+
CVariable* initializedVar = m_currShader->GetNewVariable(m_destination);
9690+
CVariable* udAlias = m_currShader->GetNewAlias(initializedVar, unsignedType, 0, m_destination->GetNumberElement());
9691+
m_encoder->SetNoMask();
9692+
m_encoder->Copy(udAlias, m_currShader->ImmToVariable(0, unsignedType));
9693+
m_encoder->Push();
9694+
9695+
m_encoder->Copy(initializedVar, m_destination);
9696+
m_encoder->Push();
9697+
9698+
m_encoder->SetNoMask();
9699+
m_encoder->Copy(m_destination, initializedVar);
9700+
m_encoder->Push();
9701+
}
9702+
}
9703+
96309704
CVariable* EmitPass::Mul(CVariable* Src0, CVariable* Src1, const CVariable* DstPrototype)
96319705
{
96329706
bool IsSrc0Imm = Src0->IsImmediate();

IGC/Compiler/CISACodeGen/EmitVISAPass.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ class EmitPass : public llvm::FunctionPass
142142
void EmitMulPair(llvm::GenIntrinsicInst* GII, const SSource Sources[4], const DstModifier& DstMod);
143143
void EmitPtrToPair(llvm::GenIntrinsicInst* GII, const SSource Sources[1], const DstModifier& DstMod);
144144
void EmitInlineAsm(llvm::CallInst* inst);
145+
void EmitInitializePHI(llvm::PHINode* phi);
145146

146147
void emitPairToPtr(llvm::GenIntrinsicInst* GII);
147148

@@ -713,7 +714,8 @@ class EmitPass : public llvm::FunctionPass
713714
template<size_t N>
714715
void JoinSIMD(CVariable* (&tempdst)[N], uint responseLength, SIMDMode mode);
715716
CVariable* BroadcastIfUniform(CVariable* pVar, bool nomask = false);
716-
bool IsNoMaskAllowed(SDAG& sdag);
717+
bool IsNoMaskAllowed(llvm::Instruction* inst);
718+
bool IsSubspanDestination(llvm::Instruction* inst);
717719
uint DecideInstanceAndSlice(const llvm::BasicBlock& blk, SDAG& sdag, bool& slicing);
718720
bool IsUndefOrZeroImmediate(const llvm::Value* value);
719721
inline bool isUndefOrConstInt0(const llvm::Value* val)

IGC/Compiler/CISACodeGen/PatternMatchPass.cpp

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,11 @@ namespace IGC
10551055
// If a phi is used in a subspan we cannot propagate the subspan use and need to use VMask
10561056
m_NeedVMask = true;
10571057

1058+
if (isSampleSource && isa<PHINode>(v))
1059+
{
1060+
m_sampleSource.insert(v);
1061+
}
1062+
10581063
if (Instruction* I = dyn_cast<Instruction>(v))
10591064
{
10601065
// this is WA for situation where application has early return (not discard) from shader
@@ -1560,7 +1565,60 @@ namespace IGC
15601565

15611566
void CodeGenPatternMatch::visitPHINode(PHINode& I)
15621567
{
1563-
// nothing to do
1568+
struct PHIPattern : Pattern
1569+
{
1570+
//bool isInDivergentLoop = false;
1571+
llvm::PHINode* phi = nullptr;
1572+
virtual void Emit(EmitPass* pass, const DstModifier& modifier)
1573+
{
1574+
IGC_ASSERT(modifier.sat == false);
1575+
IGC_ASSERT(modifier.flag == nullptr);
1576+
pass->EmitInitializePHI(phi);
1577+
}
1578+
};
1579+
1580+
if (Loop* L = LI->getLoopFor(I.getParent()))
1581+
{
1582+
SmallVector<BasicBlock*, 4> exitingBlocks;
1583+
SmallPtrSet<Instruction*, 8> visitedInstructions;
1584+
L->getExitingBlocks(exitingBlocks);
1585+
for (auto exitingBlock : exitingBlocks)
1586+
{
1587+
if (!isUniform(exitingBlock->getTerminator()))
1588+
{
1589+
std::vector<Instruction*> worklist;
1590+
worklist.push_back(&I);
1591+
while (!worklist.empty())
1592+
{
1593+
Instruction* currentInst = worklist.back();
1594+
worklist.pop_back();
1595+
for (auto operand : currentInst->operand_values())
1596+
{
1597+
if (auto nextInst = dyn_cast<Instruction>(operand))
1598+
{
1599+
if (nextInst == &I)
1600+
{
1601+
return;
1602+
}
1603+
if(L->contains(nextInst->getParent()) && !visitedInstructions.contains(nextInst))
1604+
{
1605+
worklist.push_back(nextInst);
1606+
visitedInstructions.insert(nextInst);
1607+
}
1608+
}
1609+
}
1610+
}
1611+
break;
1612+
}
1613+
}
1614+
}
1615+
if (IsSourceOfSample(&I))
1616+
{
1617+
PHIPattern* pattern = new (m_allocator) PHIPattern();
1618+
pattern->phi = &I;
1619+
//pattern->isInDivergentLoop = isInDivergentLoop;
1620+
AddPattern(pattern);
1621+
}
15641622
}
15651623

15661624
void CodeGenPatternMatch::visitBitCastInst(BitCastInst& I)
@@ -3602,6 +3660,11 @@ namespace IGC
36023660
// without improve code quality this may be refined in the future
36033661
if (inst->hasOneUse() && SupportsSaturate(inst))
36043662
{
3663+
bool isSourceOfSample = IsSourceOfSample(&I);
3664+
if (isSourceOfSample)
3665+
{
3666+
m_sampleSource.insert(inst);
3667+
}
36053668
auto *pattern = Match(*inst);
36063669
IGC_ASSERT_MESSAGE(pattern, "Failed to match pattern");
36073670
// Even though the original `inst` may support saturate,
@@ -3612,6 +3675,10 @@ namespace IGC
36123675
satPattern->pattern = pattern;
36133676
match = true;
36143677
}
3678+
else if (isSourceOfSample)
3679+
{
3680+
m_sampleSource.erase(inst);
3681+
}
36153682
}
36163683
}
36173684
if (!match)

0 commit comments

Comments
 (0)