Skip to content

Commit 01a212f

Browse files
sys-igcigcbot
authored andcommitted
Changes in code.
1 parent 30ae5f0 commit 01a212f

File tree

2 files changed

+3
-628
lines changed

2 files changed

+3
-628
lines changed

IGC/Compiler/CISACodeGen/LoopDCE.cpp

Lines changed: 3 additions & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ SPDX-License-Identifier: MIT
2626
#include "common/LLVMWarningsPop.hpp"
2727
#include "GenISAIntrinsics/GenIntrinsics.h"
2828
#include "Probe/Assertion.h"
29-
#include <functional> // for std::function
3029

3130
using namespace llvm;
3231
using namespace IGC;
@@ -89,7 +88,6 @@ namespace {
8988
AU.setPreservesCFG();
9089
AU.addRequired<CodeGenContextWrapper>();
9190
AU.addRequired<MetaDataUtilsWrapper>();
92-
AU.addRequired<LoopInfoWrapperPass>();
9391
}
9492
};
9593

@@ -216,24 +214,23 @@ char DeadPHINodeElimination::ID = 0;
216214
#undef PASS_ANALYSIS
217215

218216
#define PASS_FLAG "igc-phielimination"
219-
#define PASS_DESC "Remove Dead Recurisive PHINode"
217+
#define PASS_DESC "Remove dead recurisive PHINode"
220218
#define PASS_CFG_ONLY false
221219
#define PASS_ANALYSIS false
222220
namespace IGC {
223221
IGC_INITIALIZE_PASS_BEGIN(DeadPHINodeElimination, PASS_FLAG, PASS_DESC, PASS_CFG_ONLY, PASS_ANALYSIS)
224222
IGC_INITIALIZE_PASS_DEPENDENCY(CodeGenContextWrapper)
225223
IGC_INITIALIZE_PASS_DEPENDENCY(MetaDataUtilsWrapper)
226-
IGC_INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
227224
IGC_INITIALIZE_PASS_END(DeadPHINodeElimination, PASS_FLAG, PASS_DESC, PASS_CFG_ONLY, PASS_ANALYSIS)
228225
}
229226

230227
FunctionPass* IGC::createDeadPHINodeEliminationPass() {
231228
return new DeadPHINodeElimination();
232229
}
233230

234-
static bool eliminateDeadPHINodes(Function& F)
231+
bool DeadPHINodeElimination::runOnFunction(Function& F)
235232
{
236-
// This is to eliminate potential recursive phi like the following:
233+
// This is to eliminate potential recurive phi like the following:
237234
// Bx: x = phi [y0, B0], ...[z, Bz]
238235
// Bz: z = phi [x, Bx], ...[]
239236
// x and z are recursive phi's that are not used anywhere but in those phi's.
@@ -334,218 +331,3 @@ static bool eliminateDeadPHINodes(Function& F)
334331

335332
return (toBeDeleted.size() > 0);
336333
}
337-
338-
using BlockValueMap = DenseMap<const BasicBlock*, PHINode*>;
339-
using BlockValueMapVector = SmallVector<BlockValueMap, 16>;
340-
using BlockValueMapDuplicateIDs = SmallVector<SmallVector<size_t, 2>, 16>;
341-
342-
static BlockValueMapVector getNodeLoops(const Loop* L) {
343-
// Traverse the loop L and collect all the phi nodes
344-
// and their phi node predecessors.
345-
346-
std::function<bool(BlockValueMap&, PHINode*)> CollectConnected =
347-
[&CollectConnected](BlockValueMap& BlockMap, PHINode* P) {
348-
// Check if we have never met phi node parent (basic block) before
349-
auto Inserted = BlockMap.insert(make_pair(P->getParent(), P));
350-
351-
if (Inserted.second) {
352-
// New pair of phi node and basic block inserted
353-
// Traverse node's incoming values
354-
for (auto& V : P->incoming_values()) {
355-
if (auto N = dyn_cast<PHINode>(V))
356-
if (!CollectConnected(BlockMap, N))
357-
return false;
358-
}
359-
360-
// Return true if phi node P and all its incoming phi nodes N
361-
// have been successfully inserted into a block map
362-
return true;
363-
}
364-
365-
// Return true if phi node P have already been inserted into a block map before
366-
return Inserted.first->second == P;
367-
};
368-
369-
BlockValueMapVector BlockMaps;
370-
// Start with phi node in a header
371-
for (auto& I : *L->getHeader())
372-
if (auto P = dyn_cast<PHINode>(&I)) {
373-
BlockValueMap BlockMap;
374-
if (CollectConnected(BlockMap, P)) {
375-
BlockMaps.push_back(BlockMap);
376-
}
377-
}
378-
379-
return BlockMaps;
380-
}
381-
382-
static bool isSameTopology(const BlockValueMap& BlockMapX, const BlockValueMap& BlockMapY) {
383-
// Check if phi node recursive loops x and y
384-
// are of the same topology, e.g. each node in x
385-
// loop has unique node in y loop corresponding
386-
// to the same block.
387-
388-
if (BlockMapX.size() != BlockMapY.size())
389-
return false;
390-
391-
for (auto& PairX : BlockMapX) {
392-
auto BlockX = PairX.first;
393-
auto ValueX = PairX.second;
394-
auto PairY = BlockMapY.find(BlockX);
395-
396-
// Return false if loop of y blocks are different
397-
if (PairY == BlockMapY.end())
398-
return false;
399-
400-
auto ValueY = PairY->second;
401-
402-
// Compare two phi nodes x and y
403-
// Check if every non-phi node incomming value of x
404-
// has matching incoming value of y
405-
406-
// Loop over all incoming values of phi node x
407-
for (unsigned int i = 0; i < ValueX->getNumIncomingValues(); ++i) {
408-
auto IncomingValueX = ValueX->getIncomingValue(i);
409-
auto IncomingBlockX = ValueX->getIncomingBlock(i);
410-
411-
// Skip phi node incoming value being part of a loop
412-
if (auto IncomingPHINodeX = dyn_cast<PHINode>(IncomingValueX))
413-
if (BlockMapX.find(IncomingPHINodeX->getParent()) != BlockMapX.end())
414-
continue;
415-
416-
bool Found = false;
417-
418-
// Loop over all incoming values of phi node y
419-
for (unsigned int j = 0; j < ValueY->getNumIncomingValues(); ++j) {
420-
auto IncomingValueY = ValueY->getIncomingValue(j);
421-
auto IncomingBlockY = ValueY->getIncomingBlock(j);
422-
423-
if (IncomingValueX == IncomingValueY && IncomingBlockX == IncomingBlockY) {
424-
// Found a match
425-
Found = true;
426-
break;
427-
}
428-
}
429-
430-
// Return false if there is a non-phi node incoming value of phi node x
431-
// having no match among the incoming values of y
432-
if (!Found)
433-
return false;
434-
}
435-
}
436-
437-
return true;
438-
}
439-
440-
static BlockValueMapDuplicateIDs splitLoopsIntoDuplicateGroups(const BlockValueMapVector& BlockMaps) {
441-
// Split all found recursive phi node loops into
442-
// groups of duplicates by comparing each loop
443-
// to all others.
444-
445-
BlockValueMapDuplicateIDs DuplicatesIDs;
446-
if (BlockMaps.size()) {
447-
SmallVector<bool, 16> Found(BlockMaps.size(), false);
448-
449-
for (size_t i = 0; i < BlockMaps.size() - 1; ++i) {
450-
SmallVector<size_t, 2> Duplicates;
451-
452-
for (size_t j = i + 1; j < BlockMaps.size(); ++j)
453-
if (!Found[j] && isSameTopology(BlockMaps[i], BlockMaps[j])) {
454-
Duplicates.push_back(j);
455-
Found[j] = true;
456-
}
457-
458-
if (Duplicates.size()) {
459-
Duplicates.push_back(i);
460-
DuplicatesIDs.push_back(Duplicates);
461-
Found[i] = true;
462-
}
463-
}
464-
}
465-
466-
return DuplicatesIDs;
467-
}
468-
469-
static bool replaceNonPHINodeUses(const BlockValueMapVector& BlockMaps, const BlockValueMapDuplicateIDs& DuplicatesIDs) {
470-
// Replace all non-phi uses of nodes x with nodes y
471-
// within a group according to the correspondence maps.
472-
473-
bool Changed = false;
474-
for (size_t i = 0; i < DuplicatesIDs.size(); ++i) {
475-
auto& Duplicates = DuplicatesIDs[i];
476-
IGC_ASSERT_MESSAGE(Duplicates.size() >= 2, "Number of duplicates is expected to be at least 2");
477-
478-
// Let y be the first loop
479-
auto& BlockMapY = BlockMaps[Duplicates[0]];
480-
481-
for (auto& PairY : BlockMapY) {
482-
auto BlockY = PairY.first;
483-
auto ValueY = PairY.second;
484-
485-
// All other loops are considered x
486-
for (size_t j = 1; j < Duplicates.size(); ++j) {
487-
auto& BlockMapX = BlockMaps[Duplicates[j]];
488-
489-
auto PairX = BlockMapX.find(BlockY);
490-
IGC_ASSERT_MESSAGE(PairX != BlockMapX.end(), "Inconsistent duplicate maps");
491-
auto ValueX = PairX->second;
492-
493-
if (ValueX != ValueY)
494-
ValueX->replaceAllUsesWith(ValueY);
495-
}
496-
}
497-
}
498-
499-
return Changed;
500-
}
501-
502-
static bool resolveDuplicateLoops(Function& F, const Loop* L) {
503-
// This is to eliminate duplicate recursive phis like the following:
504-
// B0: x0 = phi [v, ...], [xN, BN]
505-
// B0: y0 = phi [v, ...], [yN, BN]
506-
// ...
507-
// B1: x1 = phi [x0, B0], ...
508-
// B1: y1 = phi [y0, B0], ...
509-
// ...
510-
// t = add %x1, 1.0
511-
// ...
512-
// B2: x2 = phi [t, ...], [x1, B1]
513-
// B2: y2 = phi [t, ...], [y1, B1]
514-
// ...
515-
// store yN ...
516-
// xi are recursive duplicate of yi, and are not used anywhere but in those phis.
517-
// Thus, they can be eliminated.
518-
519-
// Find all recursive phis within current loop L:
520-
// loops of xi, yi, etc.
521-
auto BlockMaps = getNodeLoops(L);
522-
523-
// Group all recursive phis within current loop L
524-
// into duplicate groups:
525-
// xi duplicates yi, so put then into the same group
526-
auto DuplicatesIDs = splitLoopsIntoDuplicateGroups(BlockMaps);
527-
528-
// Replace x1 with y1 in t = add %x1, 1.0,
529-
// so all xi become unused anywhere except in xi
530-
// Unused phi nodes will be eliminated by upcomming
531-
// call to eliminateDeadPHINodes(F)
532-
return replaceNonPHINodeUses(BlockMaps, DuplicatesIDs);
533-
}
534-
535-
bool DeadPHINodeElimination::runOnFunction(Function& F) {
536-
bool Changed = false;
537-
538-
if (eliminateDeadPHINodes(F))
539-
Changed = true;
540-
541-
auto LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
542-
for (auto& L : LI->getLoopsInPreorder()) {
543-
if (resolveDuplicateLoops(F, L))
544-
Changed = true;
545-
546-
if (eliminateDeadPHINodes(F))
547-
Changed = true;
548-
}
549-
550-
return Changed;
551-
}

0 commit comments

Comments
 (0)