Skip to content

Commit 4f52f84

Browse files
committed
[SILOpt] Redundant load elimination. Add debug output.
1 parent 7ea54c8 commit 4f52f84

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
lines changed

include/swift/SILOptimizer/Utils/LoadStoreOptUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ class LSBase {
173173
os << Base;
174174
Path.getValue().print(os, *Mod);
175175
}
176+
177+
virtual void dump(SILModule *Mod) { print(llvm::dbgs(), Mod); }
176178
};
177179

178180
static inline llvm::hash_code hash_value(const LSBase &S) {

lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ class BlockState {
400400
/// Returns a *single* forwardable SILValue for the given LSLocation right
401401
/// before the InsertPt instruction.
402402
SILValue reduceValuesAtEndOfBlock(RLEContext &Ctx, LSLocation &L);
403+
404+
#ifndef NDEBUG
405+
void dump(RLEContext &Ctx);
406+
#endif
403407
};
404408

405409
} // end anonymous namespace
@@ -477,6 +481,10 @@ class RLEContext {
477481
/// walked, i.e. when the we generate the genset and killset.
478482
llvm::DenseSet<SILBasicBlock *> BBWithLoads;
479483

484+
#ifndef NDEBUG
485+
SILPrintContext printCtx;
486+
#endif
487+
480488
public:
481489
RLEContext(SILFunction *F, SILPassManager *PM, AliasAnalysis *AA,
482490
TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO,
@@ -489,6 +497,8 @@ class RLEContext {
489497
/// Entry point to redundant load elimination.
490498
bool run();
491499

500+
SILFunction *getFunction() const { return Fn; }
501+
492502
/// Use a set of ad hoc rules to tell whether we should run a pessimistic
493503
/// one iteration data flow on the function.
494504
ProcessKind getProcessFunctionKind(unsigned LoadCount, unsigned StoreCount);
@@ -714,6 +724,8 @@ bool BlockState::setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem) {
714724
// forwardable values are recorded in the function.
715725
//
716726
RedundantLoads[I] = TheForwardingValue;
727+
728+
DEBUG(llvm::dbgs() << "FORWARD " << TheForwardingValue << " to" << *I);
717729
return true;
718730
}
719731

@@ -1065,9 +1077,11 @@ void BlockState::processInstructionWithKind(RLEContext &Ctx,
10651077
// that it and its operands cannot alias a load we have visited,
10661078
// invalidate that load.
10671079
if (Inst->mayWriteToMemory()) {
1080+
DEBUG(llvm::dbgs() << "WRITE " << *Inst);
10681081
processUnknownWriteInst(Ctx, Inst, Kind);
10691082
return;
10701083
}
1084+
DEBUG(llvm::dbgs() << "READ " << *Inst);
10711085
}
10721086

10731087
RLEContext::ProcessKind
@@ -1121,14 +1135,52 @@ getProcessFunctionKind(unsigned LoadCount, unsigned StoreCount) {
11211135
return ProcessKind::ProcessMultipleIterations;
11221136
}
11231137

1138+
#ifndef NDEBUG
1139+
void BlockState::dump(RLEContext &Ctx) {
1140+
for (unsigned i = 0; i < LocationNum; ++i) {
1141+
if (!isTrackingLocation(ForwardSetMax, i))
1142+
continue;
1143+
1144+
llvm::dbgs() << "Loc #" << i << ":" << (BBGenSet[i] ? " Gen" : "")
1145+
<< (BBKillSet[i] ? " Kill" : "");
1146+
if (!ForwardSetIn.empty() && ForwardSetIn.test(i)) {
1147+
llvm::dbgs() << " IN ";
1148+
ValueTableMap::const_iterator inIter = ForwardValIn.find(i);
1149+
if (inIter != ForwardValIn.end()) {
1150+
if (SILValue base = Ctx.getValue(inIter->second).getBase())
1151+
llvm::dbgs() << base;
1152+
else
1153+
llvm::dbgs() << "no base";
1154+
}
1155+
}
1156+
if (!ForwardSetOut.empty() && ForwardSetOut.test(i)) {
1157+
llvm::dbgs() << " OUT ";
1158+
ValueTableMap::const_iterator outIter = ForwardValOut.find(i);
1159+
if (outIter != ForwardValOut.end()) {
1160+
if (SILValue base = Ctx.getValue(outIter->second).getBase())
1161+
llvm::dbgs() << base;
1162+
else
1163+
llvm::dbgs() << "no base";
1164+
}
1165+
}
1166+
llvm::dbgs() << "\n";
1167+
}
1168+
}
1169+
#endif
1170+
11241171
//===----------------------------------------------------------------------===//
11251172
// RLEContext Implementation
11261173
//===----------------------------------------------------------------------===//
11271174

11281175
RLEContext::RLEContext(SILFunction *F, SILPassManager *PM, AliasAnalysis *AA,
11291176
TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO,
11301177
EpilogueARCFunctionInfo *EAFI)
1131-
: Fn(F), PM(PM), AA(AA), TE(TE), PO(PO), EAFI(EAFI) {
1178+
: Fn(F), PM(PM), AA(AA), TE(TE), PO(PO), EAFI(EAFI)
1179+
#ifndef NDEBUG
1180+
,
1181+
printCtx(llvm::dbgs(), /*Verbose=*/false, /*Sorted=*/true)
1182+
#endif
1183+
{
11321184
}
11331185

11341186
LSLocation &RLEContext::getLocation(const unsigned index) {
@@ -1306,6 +1358,10 @@ bool RLEContext::collectLocationValues(SILBasicBlock *BB, LSLocation &L,
13061358

13071359
void RLEContext::processBasicBlocksForGenKillSet() {
13081360
for (SILBasicBlock *BB : PO->getReversePostOrder()) {
1361+
DEBUG(llvm::dbgs() << "PROCESS " << printCtx.getID(BB)
1362+
<< " for Gen/Kill:\n";
1363+
BB->print(llvm::dbgs(), printCtx));
1364+
13091365
BlockState &S = getBlockState(BB);
13101366

13111367
// Compute the AvailSetMax at the beginning of the basic block.
@@ -1327,6 +1383,7 @@ void RLEContext::processBasicBlocksForGenKillSet() {
13271383

13281384
S.processInstructionWithKind(*this, &*I, RLEKind::ComputeAvailGenKillSet);
13291385
}
1386+
DEBUG(S.dump(*this));
13301387
}
13311388
}
13321389

@@ -1345,6 +1402,8 @@ void RLEContext::processBasicBlocksWithGenKillSet() {
13451402
}
13461403
while (!WorkList.empty()) {
13471404
SILBasicBlock *BB = WorkList.pop_back_val();
1405+
DEBUG(llvm::dbgs() << "PROCESS " << printCtx.getID(BB)
1406+
<< " with Gen/Kill.\n");
13481407
HandledBBs.erase(BB);
13491408

13501409
// Intersection.
@@ -1361,11 +1420,15 @@ void RLEContext::processBasicBlocksWithGenKillSet() {
13611420
WorkList.push_back(X);
13621421
}
13631422
}
1423+
DEBUG(Forwarder.dump(*this));
13641424
}
13651425
}
13661426

13671427
void RLEContext::processBasicBlocksForAvailValue() {
13681428
for (SILBasicBlock *BB : PO->getReversePostOrder()) {
1429+
DEBUG(llvm::dbgs() << "PROCESS " << printCtx.getID(BB)
1430+
<< " for available.\n");
1431+
13691432
BlockState &Forwarder = getBlockState(BB);
13701433

13711434
// Merge the predecessors. After merging, BlockState now contains
@@ -1382,11 +1445,15 @@ void RLEContext::processBasicBlocksForAvailValue() {
13821445
// the available BitVector here as they should have been initialized and
13831446
// stabilized in the processBasicBlocksWithGenKillSet.
13841447
Forwarder.updateForwardValOut();
1448+
1449+
DEBUG(Forwarder.dump(*this));
13851450
}
13861451
}
13871452

13881453
void RLEContext::processBasicBlocksForRLE(bool Optimistic) {
13891454
for (SILBasicBlock *BB : PO->getReversePostOrder()) {
1455+
DEBUG(llvm::dbgs() << "PROCESS " << printCtx.getID(BB) << " for RLE.\n");
1456+
13901457
// If we know this is not a one iteration function which means its
13911458
// forward sets have been computed and converged,
13921459
// and this basic block does not even have LoadInsts, there is no point
@@ -1402,6 +1469,8 @@ void RLEContext::processBasicBlocksForRLE(bool Optimistic) {
14021469
// beginning of the basic block along all paths.
14031470
Forwarder.mergePredecessorAvailSetAndValue(*this);
14041471

1472+
DEBUG(Forwarder.dump(*this));
1473+
14051474
// Perform the actual redundant load elimination.
14061475
Forwarder.processBasicBlockWithKind(*this, RLEKind::PerformRLE);
14071476

@@ -1478,11 +1547,10 @@ bool RLEContext::run() {
14781547
BBToProcess.find(&B) != BBToProcess.end());
14791548
}
14801549

1481-
DEBUG(llvm::dbgs() << "RLE START\n";
1482-
for (unsigned i = 0; i < LocationVault.size(); ++i) {
1483-
llvm::dbgs() << "LSLocation #" << i;
1484-
getLocation(i).print(llvm::dbgs(), &Fn->getModule());
1485-
});
1550+
DEBUG(for (unsigned i = 0; i < LocationVault.size(); ++i) {
1551+
llvm::dbgs() << "LSLocation #" << i;
1552+
getLocation(i).print(llvm::dbgs(), &Fn->getModule());
1553+
});
14861554

14871555
if (Optimistic)
14881556
runIterativeRLE();

0 commit comments

Comments
 (0)