Skip to content

Commit c7dd226

Browse files
srividyakarumurigfxbot
authored andcommitted
FindInterestingConstants pass changes.
1) Added case for multiply/div by 1. 2) Added case for selectInst. 3) Code refactoring in Finding interesting constants Change-Id: I1a32084ee4c1f818fa71bcc9dfaf4ab2a6fa61ae
1 parent 14e7f00 commit c7dd226

File tree

3 files changed

+186
-126
lines changed

3 files changed

+186
-126
lines changed

IGC/Compiler/FindInterestingConstants.cpp

Lines changed: 176 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -50,64 +50,69 @@ FindInterestingConstants::FindInterestingConstants() : FunctionPass(ID)
5050
initializeFindInterestingConstantsPass(*PassRegistry::getPassRegistry());
5151
}
5252

53-
template<typename ContextT>
54-
void FindInterestingConstants::copyInterestingConstants(ContextT* pShaderCtx)
53+
bool FindInterestingConstants::FoldsToConst(Instruction* inst, Instruction* use, bool &propagate)
5554
{
56-
pShaderCtx->programOutput.m_InterestingConstantsSize = m_InterestingConstants.size();
57-
pShaderCtx->programOutput.m_pInterestingConstants = new USC::ConstantAddrValue[m_InterestingConstants.size()];
58-
memcpy_s(pShaderCtx->programOutput.m_pInterestingConstants, m_InterestingConstants.size() * sizeof(USC::ConstantAddrValue),
59-
&m_InterestingConstants[0],
60-
m_InterestingConstants.size() * sizeof(USC::ConstantAddrValue));
61-
}
55+
propagate = false;
6256

63-
bool FindInterestingConstants::doFinalization(llvm::Module &M)
64-
{
65-
CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext();
66-
67-
if (m_InterestingConstants.size() != 0)
57+
// "use" instruction should have some operand(s)
58+
assert(use->getNumOperands() != 0);
59+
if (BranchInst* brInst = dyn_cast<BranchInst>(use))
6860
{
69-
if (ctx->type == ShaderType::PIXEL_SHADER)
70-
{
71-
PixelShaderContext* pShaderCtx = static_cast <PixelShaderContext*>(ctx);
72-
copyInterestingConstants(pShaderCtx);
73-
}
74-
else if (ctx->type == ShaderType::VERTEX_SHADER)
75-
{
76-
VertexShaderContext* pShaderCtx = static_cast <VertexShaderContext*>(ctx);
77-
copyInterestingConstants(pShaderCtx);
78-
}
79-
else if (ctx->type == ShaderType::GEOMETRY_SHADER)
80-
{
81-
GeometryShaderContext* pShaderCtx = static_cast <GeometryShaderContext*>(ctx);
82-
copyInterestingConstants(pShaderCtx);
83-
}
84-
else if (ctx->type == ShaderType::HULL_SHADER)
85-
{
86-
HullShaderContext* pShaderCtx = static_cast <HullShaderContext*>(ctx);
87-
copyInterestingConstants(pShaderCtx);
88-
}
89-
else if (ctx->type == ShaderType::DOMAIN_SHADER)
90-
{
91-
DomainShaderContext* pShaderCtx = static_cast <DomainShaderContext*>(ctx);
92-
copyInterestingConstants(pShaderCtx);
93-
}
94-
else if (ctx->type == ShaderType::COMPUTE_SHADER)
61+
m_constFoldBranch = true;
62+
return false;
63+
}
64+
65+
for (auto &U : use->operands())
66+
{
67+
Value *V = U.get();
68+
if (V == inst)
69+
continue;
70+
else if (Constant* op = dyn_cast<Constant>(V))
71+
continue;
72+
else
9573
{
96-
ComputeShaderContext* pShaderCtx = static_cast <ComputeShaderContext*>(ctx);
97-
copyInterestingConstants(pShaderCtx);
74+
// For select instruction all operands need not be constants to simplify the instruction
75+
if (SelectInst* selInst = dyn_cast<SelectInst>(use))
76+
{
77+
if (selInst->getOperand(0) == inst)
78+
return true;
79+
}
80+
else
81+
return false;
9882
}
9983
}
100-
return false;
84+
propagate = true;
85+
return true;
10186
}
10287

103-
bool FindInterestingConstants::runOnFunction(Function &F)
88+
void FindInterestingConstants::FoldsToConstPropagate(llvm::Instruction* I)
10489
{
105-
visit(F);
106-
return false;
90+
bool propagate = false;
91+
// if instruction count that can be folded to zero reached threshold, dont loop through
92+
for (auto UI = I->user_begin(), UE = I->user_end(); (UI != UE); ++UI)
93+
{
94+
if ((m_constFoldBranch) ||
95+
(m_foldsToConst >= IGC_GET_FLAG_VALUE(FoldsToConstPropThreshold)))
96+
break;
97+
98+
if (Instruction* useInst = dyn_cast<Instruction>(*UI))
99+
{
100+
if (useInst->getParent() == I->getParent()) // TBD Do we need this
101+
{
102+
if (FoldsToConst(I, useInst, propagate))
103+
{
104+
m_foldsToConst++;
105+
if (propagate)
106+
FoldsToConstPropagate(useInst);
107+
}
108+
}
109+
}
110+
}
107111
}
108112

109-
bool FindInterestingConstants::FoldsToZero(Instruction* inst, Value* use)
113+
bool FindInterestingConstants::FoldsToZero(Instruction* inst, Instruction* use)
110114
{
115+
bool propagate = false;
111116
if (BranchInst* brInst = dyn_cast<BranchInst>(use))
112117
{
113118
m_constFoldBranch = true;
@@ -125,67 +130,62 @@ bool FindInterestingConstants::FoldsToZero(Instruction* inst, Value* use)
125130
return true;
126131
}
127132
}
128-
return false;
129-
}
130-
131-
bool FindInterestingConstants::FoldsToConst(Instruction* inst, Instruction* use)
132-
{
133-
// "use" instruction should have some operand(s)
134-
assert(use->getNumOperands() != 0);
135-
if (BranchInst* brInst = dyn_cast<BranchInst>(use))
133+
if (FoldsToConst(inst, use, propagate))
136134
{
137-
m_constFoldBranch = true;
138-
return false;
135+
m_foldsToConst++;
136+
if (propagate)
137+
FoldsToConstPropagate(use);
139138
}
140-
141-
for (auto &U : use->operands())
142-
{
143-
Value *V = U.get();
144-
if (V == inst)
145-
continue;
146-
else if (Constant* op = dyn_cast<Constant>(V))
147-
continue;
148-
else
149-
return false;
150-
}
151-
return true;
139+
return false;
152140
}
153141

154142
void FindInterestingConstants::FoldsToZeroPropagate(llvm::Instruction* I)
155143
{
156-
for (auto UI = I->user_begin(), UE = I->user_end(); ((UI != UE) && (m_zeroFolded < IGC_GET_FLAG_VALUE(FoldsToZeroPropThreshold))); ++UI)
144+
for (auto UI = I->user_begin(), UE = I->user_end(); (UI != UE); ++UI)
157145
{
158146
if ((m_constFoldBranch) ||
159-
(m_zeroFolded >= IGC_GET_FLAG_VALUE(FoldsToZeroPropThreshold)))
147+
(m_foldsToZero >= IGC_GET_FLAG_VALUE(FoldsToZeroPropThreshold)))
160148
break;
161149
if (Instruction* useInst = dyn_cast<Instruction>(*UI))
162150
{
163151
if (FoldsToZero(I, useInst))
164152
{
165-
m_zeroFolded++;
153+
m_foldsToZero++;
166154
FoldsToZeroPropagate(useInst);
167155
}
168156
}
169157
}
170158
}
171159

172-
void FindInterestingConstants::FoldsToConstPropagate(llvm::Instruction* I)
160+
bool FindInterestingConstants::FoldsToSource(llvm::Instruction* inst, llvm::Instruction* use)
173161
{
174-
// if instruction count that can be folded to zero reached threshold, dont loop through
175-
for (auto UI = I->user_begin(), UE = I->user_end(); (UI != UE); ++UI)
162+
if (BinaryOperator *binInst = dyn_cast<BinaryOperator>(use))
176163
{
177-
if ((m_constFoldBranch) ||
178-
(m_constFolded >= IGC_GET_FLAG_VALUE(FoldsToConstPropThreshold)))
179-
break;
164+
if (binInst->getOpcode() == Instruction::FMul)
165+
{
166+
return true;
167+
}
168+
else if (binInst->getOpcode() == Instruction::FDiv &&
169+
inst == binInst->getOperand(1))
170+
{
171+
return true;
172+
}
173+
}
174+
return false;
175+
}
180176

177+
void FindInterestingConstants::FoldsToSourcePropagate(llvm::Instruction* I)
178+
{
179+
for (auto UI = I->user_begin(), UE = I->user_end(); UI != UE; ++UI)
180+
{
181181
if (Instruction* useInst = dyn_cast<Instruction>(*UI))
182182
{
183-
if (useInst->getParent() == I->getParent()) // TBD Do we need this
183+
if (FoldsToSource(I, useInst))
184184
{
185-
if (FoldsToConst(I,useInst))
185+
m_foldsToSource++;
186+
if (m_foldsToSource >= IGC_GET_FLAG_VALUE(FoldsToSourceThreshold))
186187
{
187-
m_constFolded++;
188-
FoldsToConstPropagate(useInst);
188+
break;
189189
}
190190
}
191191
}
@@ -265,60 +265,117 @@ void FindInterestingConstants::addInterestingConstant(CodeGenContext* ctx, unsig
265265
void FindInterestingConstants::visitLoadInst(llvm::LoadInst &I)
266266
{
267267
CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext();
268-
bool isInteresting = false;
269268
unsigned bufId;
270269
unsigned eltId;
271270
int size_in_bytes;
272-
bool anyValue;
273271

274-
m_zeroFolded = 0;
275-
m_constFolded = 0;
272+
m_foldsToZero = 0;
273+
m_foldsToConst = 0;
274+
m_foldsToSource = 0;
276275
m_constFoldBranch = false;
277-
anyValue = true;
278276
if(getConstantAddress(I, bufId, eltId, size_in_bytes))
279277
{
280-
for (auto UI = I.user_begin(), UE = I.user_end(); UI != UE; ++UI)
278+
/*
279+
This Constant is interesting, if the use instruction:
280+
is branch
281+
or subsequent Instructions get folded to constant if the constant value is known
282+
or subsequent Instructions get folded to zero if the constant value is 0
283+
or subsequent Instructions get folded to its source if the constant value is 1 (mul/div by 1 scenarios)
284+
*/
285+
FoldsToConstPropagate(&I);
286+
// If m_foldsToConst is greater than threshold or some branch instruction gets simplified because of this constant
287+
if ((m_constFoldBranch) || (m_foldsToConst >= IGC_GET_FLAG_VALUE(FoldsToConstPropThreshold)))
288+
{
289+
// Get the ConstantAddress from LoadInst and log it in interesting constants
290+
addInterestingConstant(ctx, bufId, eltId, size_in_bytes, true);
291+
}
292+
else
281293
{
282-
if (Instruction* useInst = dyn_cast<Instruction>(*UI))
294+
m_foldsToConst = 0; // Reset FoldsToConst count to zero. We can keep looking for this case when FoldsToZero cannot be propagated further
295+
FoldsToZeroPropagate(&I);
296+
// If m_foldsToZero is greater than threshold or some branch instruction gets simplified because of this constant
297+
if ((m_constFoldBranch) ||
298+
((m_foldsToZero + m_foldsToConst) >= IGC_GET_FLAG_VALUE(FoldsToZeroPropThreshold)))
283299
{
284-
/*
285-
This Constant is interesting, if the use instruction:
286-
is branch
287-
and subsequent Instructions get folded to zero if the constant value is 0 (FoldsToZeroPropThreshold)
288-
and subsequent Instructions get folded to constant if the constant value is known
289-
*/
290-
291-
if (FoldsToConst(&I, useInst))
292-
{
293-
m_constFolded++;
294-
FoldsToConstPropagate(useInst);
295-
}
296-
// If m_constFolded is greater than threshold or some branch instruction gets simplified because of this constant
297-
if ((m_constFoldBranch) || (m_constFolded >= IGC_GET_FLAG_VALUE(FoldsToConstPropThreshold)))
298-
{
299-
isInteresting = true;
300-
break;
301-
}
302-
303-
if (FoldsToZero(&I, useInst))
304-
{
305-
anyValue = false;
306-
m_zeroFolded++;
300+
// Zero value for this constant is interesting
301+
// Get the ConstantAddress from LoadInst and log it in interesting constants
302+
addInterestingConstant(ctx, bufId, eltId, size_in_bytes, false, 0);
303+
// Continue finding if ONE_VALUE is beneficial for this constant
304+
}
307305

308-
FoldsToZeroPropagate(useInst);
306+
FoldsToSourcePropagate(&I);
307+
if (m_foldsToSource >= IGC_GET_FLAG_VALUE(FoldsToSourceThreshold))
308+
{
309+
// One value for this constant is interesting
310+
// Get the ConstantAddress from LoadInst and log it in interesting constants
311+
if (I.getType()->isIntegerTy())
312+
{
313+
addInterestingConstant(ctx, bufId, eltId, size_in_bytes, false, 1);
309314
}
310-
// If m_zeroFolded is greater than threshold or some branch instruction gets simplified because of this constant
311-
if ((m_constFoldBranch) || (m_zeroFolded >= IGC_GET_FLAG_VALUE(FoldsToZeroPropThreshold)))
315+
else if (I.getType()->isFloatTy())
312316
{
313-
isInteresting = true;
314-
break;
317+
uint32_t value;
318+
float floatValue = 1.0;
319+
memcpy_s(&value, sizeof(uint32_t), &floatValue, sizeof(float));
320+
addInterestingConstant(ctx, bufId, eltId, size_in_bytes, false, value);
315321
}
316322
}
317323
}
318-
if (isInteresting)
324+
}
325+
}
326+
327+
template<typename ContextT>
328+
void FindInterestingConstants::copyInterestingConstants(ContextT* pShaderCtx)
329+
{
330+
pShaderCtx->programOutput.m_InterestingConstantsSize = m_InterestingConstants.size();
331+
pShaderCtx->programOutput.m_pInterestingConstants = new USC::ConstantAddrValue[m_InterestingConstants.size()];
332+
memcpy_s(pShaderCtx->programOutput.m_pInterestingConstants, m_InterestingConstants.size() * sizeof(USC::ConstantAddrValue),
333+
&m_InterestingConstants[0],
334+
m_InterestingConstants.size() * sizeof(USC::ConstantAddrValue));
335+
}
336+
337+
bool FindInterestingConstants::doFinalization(llvm::Module &M)
338+
{
339+
CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext();
340+
341+
if (m_InterestingConstants.size() != 0)
342+
{
343+
if (ctx->type == ShaderType::PIXEL_SHADER)
344+
{
345+
PixelShaderContext* pShaderCtx = static_cast <PixelShaderContext*>(ctx);
346+
copyInterestingConstants(pShaderCtx);
347+
}
348+
else if (ctx->type == ShaderType::VERTEX_SHADER)
349+
{
350+
VertexShaderContext* pShaderCtx = static_cast <VertexShaderContext*>(ctx);
351+
copyInterestingConstants(pShaderCtx);
352+
}
353+
else if (ctx->type == ShaderType::GEOMETRY_SHADER)
319354
{
320-
// Get the ConstantAddress from LoadInst and log it in interesting constants
321-
addInterestingConstant(ctx, bufId, eltId, size_in_bytes, anyValue);
355+
GeometryShaderContext* pShaderCtx = static_cast <GeometryShaderContext*>(ctx);
356+
copyInterestingConstants(pShaderCtx);
357+
}
358+
else if (ctx->type == ShaderType::HULL_SHADER)
359+
{
360+
HullShaderContext* pShaderCtx = static_cast <HullShaderContext*>(ctx);
361+
copyInterestingConstants(pShaderCtx);
362+
}
363+
else if (ctx->type == ShaderType::DOMAIN_SHADER)
364+
{
365+
DomainShaderContext* pShaderCtx = static_cast <DomainShaderContext*>(ctx);
366+
copyInterestingConstants(pShaderCtx);
367+
}
368+
else if (ctx->type == ShaderType::COMPUTE_SHADER)
369+
{
370+
ComputeShaderContext* pShaderCtx = static_cast <ComputeShaderContext*>(ctx);
371+
copyInterestingConstants(pShaderCtx);
322372
}
323373
}
374+
return false;
375+
}
376+
377+
bool FindInterestingConstants::runOnFunction(Function &F)
378+
{
379+
visit(F);
380+
return false;
324381
}

IGC/Compiler/FindInterestingConstants.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,20 @@ namespace IGC
6767
void visitLoadInst(llvm::LoadInst &I);
6868

6969
private:
70-
unsigned int m_zeroFolded;
71-
unsigned int m_constFolded;
70+
unsigned int m_foldsToZero;
71+
unsigned int m_foldsToConst;
72+
unsigned int m_foldsToSource;
7273
bool m_constFoldBranch;
7374
std::vector<USC::ConstantAddrValue> m_InterestingConstants;
7475

7576
// Helper functions
7677
bool getConstantAddress(llvm::LoadInst &I, unsigned &bufId, unsigned &eltId, int &size_in_bytes);
77-
bool FoldsToZero(llvm::Instruction* inst, llvm::Value* use);
78-
bool FoldsToConst(llvm::Instruction* inst, llvm::Instruction* use);
79-
void FoldsToZeroPropagate(llvm::Instruction* I);
78+
bool FoldsToConst(llvm::Instruction* inst, llvm::Instruction* use, bool &propagate);
79+
bool FoldsToZero(llvm::Instruction* inst, llvm::Instruction* use);
80+
bool FoldsToSource(llvm::Instruction* inst, llvm::Instruction* use);
8081
void FoldsToConstPropagate(llvm::Instruction* I);
82+
void FoldsToZeroPropagate(llvm::Instruction* I);
83+
void FoldsToSourcePropagate(llvm::Instruction* I);
8184
void addInterestingConstant(CodeGenContext* ctx, unsigned bufId, unsigned eltId, int size_in_bytes, bool anyValue, uint32_t value);
8285
template<typename ContextT>
8386
void copyInterestingConstants(ContextT* pShaderCtx);

0 commit comments

Comments
 (0)