@@ -50,64 +50,69 @@ FindInterestingConstants::FindInterestingConstants() : FunctionPass(ID)
50
50
initializeFindInterestingConstantsPass (*PassRegistry::getPassRegistry ());
51
51
}
52
52
53
- template <typename ContextT>
54
- void FindInterestingConstants::copyInterestingConstants (ContextT* pShaderCtx)
53
+ bool FindInterestingConstants::FoldsToConst (Instruction* inst, Instruction* use, bool &propagate)
55
54
{
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 ;
62
56
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))
68
60
{
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
95
73
{
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 ;
98
82
}
99
83
}
100
- return false ;
84
+ propagate = true ;
85
+ return true ;
101
86
}
102
87
103
- bool FindInterestingConstants::runOnFunction (Function &F )
88
+ void FindInterestingConstants::FoldsToConstPropagate (llvm::Instruction* I )
104
89
{
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
+ }
107
111
}
108
112
109
- bool FindInterestingConstants::FoldsToZero (Instruction* inst, Value * use)
113
+ bool FindInterestingConstants::FoldsToZero (Instruction* inst, Instruction * use)
110
114
{
115
+ bool propagate = false ;
111
116
if (BranchInst* brInst = dyn_cast<BranchInst>(use))
112
117
{
113
118
m_constFoldBranch = true ;
@@ -125,67 +130,62 @@ bool FindInterestingConstants::FoldsToZero(Instruction* inst, Value* use)
125
130
return true ;
126
131
}
127
132
}
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))
136
134
{
137
- m_constFoldBranch = true ;
138
- return false ;
135
+ m_foldsToConst++;
136
+ if (propagate)
137
+ FoldsToConstPropagate (use);
139
138
}
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 ;
152
140
}
153
141
154
142
void FindInterestingConstants::FoldsToZeroPropagate (llvm::Instruction* I)
155
143
{
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)
157
145
{
158
146
if ((m_constFoldBranch) ||
159
- (m_zeroFolded >= IGC_GET_FLAG_VALUE (FoldsToZeroPropThreshold)))
147
+ (m_foldsToZero >= IGC_GET_FLAG_VALUE (FoldsToZeroPropThreshold)))
160
148
break ;
161
149
if (Instruction* useInst = dyn_cast<Instruction>(*UI))
162
150
{
163
151
if (FoldsToZero (I, useInst))
164
152
{
165
- m_zeroFolded ++;
153
+ m_foldsToZero ++;
166
154
FoldsToZeroPropagate (useInst);
167
155
}
168
156
}
169
157
}
170
158
}
171
159
172
- void FindInterestingConstants::FoldsToConstPropagate (llvm::Instruction* I )
160
+ bool FindInterestingConstants::FoldsToSource (llvm::Instruction* inst, llvm::Instruction* use )
173
161
{
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))
176
163
{
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
+ }
180
176
177
+ void FindInterestingConstants::FoldsToSourcePropagate (llvm::Instruction* I)
178
+ {
179
+ for (auto UI = I->user_begin (), UE = I->user_end (); UI != UE; ++UI)
180
+ {
181
181
if (Instruction* useInst = dyn_cast<Instruction>(*UI))
182
182
{
183
- if (useInst-> getParent () == I-> getParent ()) // TBD Do we need this
183
+ if (FoldsToSource (I, useInst))
184
184
{
185
- if (FoldsToConst (I,useInst))
185
+ m_foldsToSource++;
186
+ if (m_foldsToSource >= IGC_GET_FLAG_VALUE (FoldsToSourceThreshold))
186
187
{
187
- m_constFolded++;
188
- FoldsToConstPropagate (useInst);
188
+ break ;
189
189
}
190
190
}
191
191
}
@@ -265,60 +265,117 @@ void FindInterestingConstants::addInterestingConstant(CodeGenContext* ctx, unsig
265
265
void FindInterestingConstants::visitLoadInst (llvm::LoadInst &I)
266
266
{
267
267
CodeGenContext* ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext ();
268
- bool isInteresting = false ;
269
268
unsigned bufId;
270
269
unsigned eltId;
271
270
int size_in_bytes;
272
- bool anyValue;
273
271
274
- m_zeroFolded = 0 ;
275
- m_constFolded = 0 ;
272
+ m_foldsToZero = 0 ;
273
+ m_foldsToConst = 0 ;
274
+ m_foldsToSource = 0 ;
276
275
m_constFoldBranch = false ;
277
- anyValue = true ;
278
276
if (getConstantAddress (I, bufId, eltId, size_in_bytes))
279
277
{
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
281
293
{
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)))
283
299
{
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
+ }
307
305
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 );
309
314
}
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 ())
312
316
{
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);
315
321
}
316
322
}
317
323
}
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)
319
354
{
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);
322
372
}
323
373
}
374
+ return false ;
375
+ }
376
+
377
+ bool FindInterestingConstants::runOnFunction (Function &F)
378
+ {
379
+ visit (F);
380
+ return false ;
324
381
}
0 commit comments