@@ -239,8 +239,6 @@ int DiagnosticInfoOverlappingArgs::KindID = 0;
239
239
class CMABIAnalysis : public ModulePass {
240
240
// This map captures all global variables to be localized.
241
241
std::vector<LocalizationInfo *> LocalizationInfoObjs;
242
- GlobalsLocalizationConfig::LimitT GlobalsLocalizationLimit = 0 ;
243
- bool LocalizeVectorGlobals = false ;
244
242
245
243
public:
246
244
static char ID;
@@ -355,118 +353,14 @@ INITIALIZE_PASS_DEPENDENCY(GenXBackendConfig)
355
353
INITIALIZE_PASS_END(CMABIAnalysis, " cmabi-analysis" ,
356
354
" Fix ABI issues for the genx backend" , false , true )
357
355
358
- static std::size_t
359
- defineGlobalsLocalizationLimit(const GenXBackendConfig &Config) {
360
- if (Config.isGlobalsLocalizationForced ())
361
- return GlobalsLocalizationConfig::NoLimit;
362
-
363
- // Half of a size of standard GenX register file in bytes.
364
- // 128 * 32 / 2
365
- constexpr std::size_t HalfGRF = 2048 ;
366
- std::size_t Limit = Config.getGlobalsLocalizationLimit ();
367
- return std::min (Limit, HalfGRF);
368
- }
369
-
370
356
bool CMABIAnalysis::runOnModule(Module &M) {
371
357
auto &&BCfg = getAnalysis<GenXBackendConfig>();
372
- GlobalsLocalizationLimit = defineGlobalsLocalizationLimit (BCfg);
373
- LocalizeVectorGlobals = BCfg.isVectorGlobalsLocalizationForced ();
374
358
FCtrl = BCfg.getFCtrl ();
375
359
376
360
runOnCallGraph (getAnalysis<CallGraphWrapperPass>().getCallGraph ());
377
361
return false ;
378
362
}
379
363
380
- // Currently weight of the global defines by its size
381
- static int calcGVWeight (const GlobalVariable &GV, const DataLayout &DL) {
382
- if (!GV.getValueType ()->isVectorTy ())
383
- return DL.getTypeAllocSize (GV.getValueType ());
384
- // Alignment rules are too restrictive for vectors and cannot be reduced
385
- // (even though LangRef says that they can).
386
- // GRF width (32) alignment was taken as it is considered that localized
387
- // global vectors should be eventually promoted to GRF.
388
- return alignTo (DL.getTypeStoreSize (GV.getValueType ()), 32 );
389
- }
390
-
391
- // selectGlobalsToLocalize - chooses which globals to localize.
392
- // Returns std::vector of std::reference_wrapper to such globals.
393
- //
394
- // Algorithm: exclude globals that definitely should not be localized, include
395
- // those that definitely should. If the total weight of the already chosen
396
- // globals doesn't exceed \p Bound, sort the remaining globals by weight,
397
- // choose first lightest ones, so the total weight is under \p Bound.
398
- //
399
- // \p Globals - range of globals to choose from
400
- // \p Bound - bound not to overcome
401
- // \p ExcludePred - functor : GVRef -> bool, true if global should not be
402
- // localized
403
- // \p InlcudePred - functor : GVRef -> bool, true if the provided global must
404
- // be localized
405
- // \p WeightCalculator - functor : GVRef -> decltype(Bound), returns
406
- // weight of global
407
- template <typename ForwardRange, typename ExcludePredT, typename IncludePredT,
408
- typename T, typename WeightCalculatorT>
409
- auto selectGlobalsToLocalize (ForwardRange Globals, T Bound,
410
- ExcludePredT ExcludePred, IncludePredT IncludePred,
411
- WeightCalculatorT WeightCalculator) {
412
- IGC_ASSERT_MESSAGE (Bound >= 0 , " bound must be nonnegative" );
413
- using GVRef = vc::ranges::range_reference_t <ForwardRange>;
414
- using GVT = std::remove_reference_t <GVRef>;
415
- using GVRefWrapper = std::reference_wrapper<GVT>;
416
-
417
- IGC_ASSERT_MESSAGE (std::none_of (Globals.begin (), Globals.end (),
418
- [ExcludePred, IncludePred](GVRef GV) {
419
- return ExcludePred (GV) && IncludePred (GV);
420
- }),
421
- " 'must include' and 'must exclude' sets must be disjoint" );
422
-
423
- if (Bound == GlobalsLocalizationConfig::NoLimit) {
424
- std::vector<GVRefWrapper> ToLocalize;
425
- // filter out those, that we must exclude
426
- std::copy_if (Globals.begin (), Globals.end (), std::back_inserter (ToLocalize),
427
- [ExcludePred](GVRef GV) { return !ExcludePred (GV); });
428
- return ToLocalize;
429
- }
430
-
431
- std::vector<GVRefWrapper> ToLocalize;
432
- // Adding those that we must include.
433
- std::copy_if (Globals.begin (), Globals.end (), std::back_inserter (ToLocalize),
434
- IncludePred);
435
- if (Bound == 0 )
436
- return ToLocalize;
437
-
438
- T IncludeWeight =
439
- std::accumulate (ToLocalize.begin (), ToLocalize.end (), static_cast <T>(0 ),
440
- [WeightCalculator](T Prev, GVRef GV) {
441
- return Prev + WeightCalculator (GV);
442
- });
443
- if (IncludeWeight >= Bound)
444
- return ToLocalize;
445
-
446
- std::vector<GVRefWrapper> Remainder;
447
- std::copy_if (Globals.begin (), Globals.end (), std::back_inserter (Remainder),
448
- [IncludePred, ExcludePred](GVRef GV) {
449
- return !IncludePred (GV) && !ExcludePred (GV);
450
- });
451
- // Sorting remaining globals by weight.
452
- std::sort (Remainder.begin (), Remainder.end (),
453
- [WeightCalculator](GVRef LHS, GVRef RHS) {
454
- return WeightCalculator (LHS) < WeightCalculator (RHS);
455
- });
456
-
457
- T RemainderBound = Bound - IncludeWeight;
458
- // filter max number of lightest ones, which weight sum is under the bound
459
- auto FirstNotToLocalize = vc::upper_partial_sum_bound (
460
- Remainder.begin (), Remainder.end (), RemainderBound,
461
- [WeightCalculator](T Base, GVRef Inc) {
462
- return Base + WeightCalculator (Inc);
463
- });
464
-
465
- std::copy (Remainder.begin (), FirstNotToLocalize,
466
- std::back_inserter (ToLocalize));
467
- return ToLocalize;
468
- }
469
-
470
364
bool CMABIAnalysis::runOnCallGraph (CallGraph &CG) {
471
365
// Analyze global variable usages and for each function attaches global
472
366
// variables to be copy-in and copy-out.
@@ -541,45 +435,25 @@ bool CMABI::runOnSCC(CallGraphSCC &SCC) {
541
435
return Changed;
542
436
}
543
437
544
- // Whether \p Inst is an instruction on which IR rebuild caused by addrspace
545
- // change will stop.
546
- static bool isRebuildTerminal (const Instruction &Inst) {
547
- // Result of a load inst is no longer a pointer so here propogation will stop.
548
- if (isa<LoadInst>(Inst) || isa<AddrSpaceCastInst>(Inst) ||
549
- isa<StoreInst>(Inst))
550
- return true ;
551
- if (!isa<IntrinsicInst>(Inst))
552
- return false ;
553
- auto IID = cast<IntrinsicInst>(Inst).getIntrinsicID ();
554
- return IID == Intrinsic::masked_gather || IID == Intrinsic::masked_scatter;
555
- }
556
-
557
438
// Replaces uses of global variables with the corresponding allocas inside a
558
439
// specified function. More insts can be rebuild if global variable addrspace
559
440
// wasn't private.
560
441
static void replaceUsesWithinFunction (
561
442
const SmallDenseMap<Value *, Value *> &GlobalsToReplace, Function *F) {
562
- auto ToRebuild = vc::MakeRebuildInfoBuilder (
563
- [](const Instruction &Inst) { return isRebuildTerminal (Inst); });
564
- ReversePostOrderTraversal<Function *> RPOT (F);
565
- for (auto *BB : RPOT) {
566
- for (auto &Inst : *BB) {
443
+ for (auto &BB : *F) {
444
+ for (auto &Inst : BB) {
567
445
for (unsigned i = 0 , e = Inst.getNumOperands (); i < e; ++i) {
568
446
Value *Op = Inst.getOperand (i);
569
447
auto Iter = GlobalsToReplace.find (Op);
570
448
if (Iter != GlobalsToReplace.end ()) {
571
- if (Op->getType () == Iter->second ->getType ())
572
- Inst.setOperand (i, Iter->second );
573
- else {
574
- ToRebuild.addEntry (Inst, i, *Iter->second );
575
- }
576
- } else {
577
- ToRebuild.addNodeIfRequired (Inst, i);
449
+ IGC_ASSERT_MESSAGE (Op->getType () == Iter->second ->getType (),
450
+ " only global variables in private addrspace are "
451
+ " localized, so types must match" );
452
+ Inst.setOperand (i, Iter->second );
578
453
}
579
454
}
580
455
}
581
456
}
582
- vc::MakeInstructionRebuilder (std::move (ToRebuild).emit ()).rebuild ();
583
457
}
584
458
585
459
// \brief Create allocas for globals directly used in this kernel and
@@ -1534,21 +1408,15 @@ void CMABIAnalysis::analyzeGlobals(CallGraph &CG) {
1534
1408
if (M.global_empty ())
1535
1409
return ;
1536
1410
1537
- const auto &DL = M.getDataLayout ();
1538
- auto ToLocalize = selectGlobalsToLocalize (
1539
- M.globals (), GlobalsLocalizationLimit,
1540
- [](const GlobalVariable &GV) {
1541
- // Don't localize global constant format string, as it must be
1542
- // relocated in case of zebin printf.
1543
- // FIXME: what if we force localization.
1544
- return GV.hasAttribute (genx::FunctionMD::GenXVolatile) ||
1545
- vc::isConstantString (GV);
1546
- },
1547
- [IncludeVectors = LocalizeVectorGlobals](const GlobalVariable &GV) {
1548
- return IncludeVectors && GV.getValueType ()->isVectorTy () &&
1549
- !GV.hasAttribute (genx::FunctionMD::GenXVolatile);
1550
- },
1551
- [&DL](const GlobalVariable &GV) { return calcGVWeight (GV, DL); });
1411
+ // FIXME: String constants must be localized too. Excluding them there
1412
+ // to WA legacy printf implementation in CM FE (printf strings are
1413
+ // not in constant addrspace in legacy printf).
1414
+ auto ToLocalize =
1415
+ make_filter_range (M.globals (), [](const GlobalVariable &GV) {
1416
+ return GV.getAddressSpace () == PrivateAddrSpace &&
1417
+ !GV.hasAttribute (genx::FunctionMD::GenXVolatile) &&
1418
+ !vc::isConstantString (GV);
1419
+ });
1552
1420
1553
1421
// Collect direct and indirect (GV is used in a called function)
1554
1422
// uses of globals.
0 commit comments