Skip to content

Commit c815be9

Browse files
bgajdaINTCsys_zuul
authored andcommitted
This pass is after ProgramScopeConstantAnalysis, which propagates llvm.used GV. Because of that, there is one additional Constant user (not GEPs), and pass would stop early, so let's ignore this specific one. Also added flag to ignore loop requirement. (disabled by default) With this and with modifying ConstantPromotionSize, we can promote bigger tables to registers for experiments.
Change-Id: I9f4dee238aefeb8faf65cbb3ae2b39ebea2017f0
1 parent d573da8 commit c815be9

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

IGC/Compiler/CISACodeGen/SimplifyConstant.cpp

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,29 @@ FunctionPass* IGC::createPromoteConstantPass() { return new PromoteConstant(); }
260260
//
261261
// We only promote when there is load of GV inside loops.
262262
//
263-
static bool checkUses(GlobalVariable* GV, const Function* F, LoopInfo& LI) {
263+
static bool checkUses(GlobalVariable* GV, const Function* F, LoopInfo& LI, const ConstantArray* llvm_used) {
264264
bool LoadInLoop = false;
265265
for (auto U : GV->users()) {
266+
// Because of ProgramScopeConstantAnalysis there might be user in llvm.used
267+
// let's ignore this one, as it doesn't prevent opt.
268+
// TODO: is there any other case of Constant to worry about. (?)
269+
if (auto Const = dyn_cast<Constant>(U))
270+
{
271+
bool foundInLLVMUsed = false;
272+
unsigned numOperands = llvm_used ? llvm_used->getNumOperands() : 0;
273+
for (unsigned i = 0; i != numOperands; ++i)
274+
{
275+
Value* gvi = llvm_used->getOperand(i)->stripPointerCastsNoFollowAliases();
276+
if (gvi == Const->stripPointerCastsNoFollowAliases())
277+
{
278+
foundInLLVMUsed = true;
279+
break;
280+
}
281+
}
282+
if (foundInLLVMUsed)
283+
continue;
284+
}
285+
266286
auto Inst = dyn_cast<Instruction>(U);
267287
if (!Inst)
268288
// TODO: this may be a const expr.
@@ -284,6 +304,9 @@ static bool checkUses(GlobalVariable* GV, const Function* F, LoopInfo& LI) {
284304
}
285305
}
286306

307+
if (IGC_IS_FLAG_ENABLED(AllowNonLoopConstantPromotion))
308+
return true;
309+
287310
return LoadInLoop;
288311
}
289312

@@ -342,6 +365,11 @@ static bool checkSize(GlobalVariable* GV, VectorType*& DataType,
342365
N *= VectorSize;
343366
}
344367
unsigned VS = getLegalVectorSize(N);
368+
369+
// Allow experimental overriding for bigger than 32 elem. tables
370+
if (IGC_IS_FLAG_ENABLED(AllowNonLoopConstantPromotion))
371+
VS = 1U << Log2_32_Ceil(N);
372+
345373
if (VS == 0)
346374
return false;
347375

@@ -409,7 +437,7 @@ static bool checkType(GlobalVariable* GV) {
409437
if (auto CDA = dyn_cast<ConstantDataArray>(Init))
410438
return !CDA->isString();
411439

412-
// Not simply data. Need to check if all emements have the same type in a
440+
// Not simply data. Need to check if all elements have the same type in a
413441
// constant array.
414442
if (auto CA = dyn_cast<ConstantArray>(Init)) {
415443
auto EltTy = CA->getType()->getElementType();
@@ -499,8 +527,8 @@ static void promote(GlobalVariable* GV, VectorType* AllocaType, bool IsSigned,
499527
// Transform all uses
500528
for (auto UI = GV->user_begin(); UI != GV->user_end(); /*empty*/) {
501529
auto GEP = dyn_cast<GetElementPtrInst>(*UI++);
502-
assert(GEP && "nullptr");
503-
if (GEP->getParent()->getParent() != F)
530+
// might be Constant user in llvm.used
531+
if (!GEP || GEP->getParent()->getParent() != F)
504532
continue;
505533
assert(GEP->getNumIndices() == 2);
506534
// This is the index to address the array, and the first index is to address
@@ -569,8 +597,8 @@ static bool rewriteAsCmpSel(GlobalVariable* GV, Function& F) {
569597

570598
for (auto UI = GV->user_begin(); UI != GV->user_end(); /*empty*/) {
571599
auto GEP = dyn_cast<GetElementPtrInst>(*UI++);
572-
assert(GEP && "nullptr");
573-
if (GEP->getParent()->getParent() != &F)
600+
// might be Constant user in llvm.used
601+
if (!GEP || GEP->getParent()->getParent() != &F)
574602
continue;
575603

576604
// This is the index to address the array, and the first index is to
@@ -634,14 +662,17 @@ bool PromoteConstant::runOnFunction(Function& F) {
634662
Module* M = F.getParent();
635663
bool Changed = false;
636664

665+
auto gv = M->getGlobalVariable("llvm.used");
666+
ConstantArray* llvm_used = gv ? dyn_cast_or_null<ConstantArray>(gv->getInitializer()) : nullptr;
667+
637668
for (auto I = M->global_begin(); I != M->global_end(); /*empty*/) {
638669
GlobalVariable* GV = &(*I++);
639670
if (GV->user_empty() || !GV->isConstant() || !GV->hasInitializer() ||
640671
GV->getType()->getAddressSpace() != ADDRESS_SPACE_CONSTANT)
641672
continue;
642673
if (!checkType(GV))
643674
continue;
644-
if (!checkUses(GV, &F, LI))
675+
if (!checkUses(GV, &F, LI, llvm_used))
645676
continue;
646677

647678
// Rewrite as cmp+sel sequence if profitable.

IGC/common/igc_flags.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ DECLARE_IGC_REGKEY(bool, EnableThreadCombiningWithNoSLM, false, "Enable thread c
287287
DECLARE_IGC_REGKEY(DWORD, SubroutineThreshold, 110000, "Minimal kernel size to enable subroutines")
288288
DECLARE_IGC_REGKEY(DWORD, SubroutineInlinerThreshold, 3000, "Subroutine inliner threshold")
289289
DECLARE_IGC_REGKEY(bool, EnableConstantPromotion, true, "Enable global constant data to register promotion")
290+
DECLARE_IGC_REGKEY(bool, AllowNonLoopConstantPromotion, false, "Allows promotion for constants not in loop (e.g. used once)")
290291
DECLARE_IGC_REGKEY(DWORD, ConstantPromotionSize, 2, "Threshold in number of GRFs")
291292
DECLARE_IGC_REGKEY(DWORD, ConstantPromotionCmpSelSize, 4, "Array size threshold for cmp-sel transform")
292293
DECLARE_IGC_REGKEY(bool, EnableVariableReuse, true, "Enable local variable reuse")

0 commit comments

Comments
 (0)