Skip to content

Commit 035b1f3

Browse files
smilczekigcbot
authored andcommitted
Minor fixes and refactors.
Change args to const ref where makes sense. Put std::move where makes sense Apply rule of three Change usage of unique_ptr and ptrs to unique_ptr to use just shared_ptr Update comment in CodeSinking Use saved boolean value instead of calling method over and over.
1 parent 2b1b933 commit 035b1f3

File tree

15 files changed

+75
-74
lines changed

15 files changed

+75
-74
lines changed

IGC/AdaptorOCL/preprocess_spvir/PromoteBools.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ Type *PromoteBools::getOrCreatePromotedType(Type *type) {
325325
// types do not have this problem.
326326
if (typeNeedsPromotion(structType)) {
327327
// Create an opaque type to handle recursive types
328-
auto name = structType->hasName() ? structType->getName().str() : "";
328+
const auto &name = structType->hasName() ? structType->getName().str() : "";
329329
structType->setName(name + ".unpromoted");
330330

331331
auto newStructType = StructType::create(type->getContext(), name);

IGC/BiFManager/BiFManagerTool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ void BiFManagerTool::writeHashMap(llvm::raw_fd_ostream &fileDataHeader, BiFDicti
8989
std::map<size_t, std::vector<std::string>> sortBySizeNameFunc;
9090

9191
for (auto rec_i = ListOfFunctions->begin(); rec_i != ListOfFunctions->end(); ++rec_i) {
92-
auto record_inst = *rec_i;
92+
const auto &record_inst = *rec_i;
9393
const std::string &funcName =
9494
record_inst.first;
9595

IGC/Compiler/CISACodeGen/CodeSinking.cpp

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,9 +1065,9 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
10651065
auto getLeafInstToCandidateMap = [&](BasicBlock *TgtBB, CandidatePtrVec &Candidates,
10661066
InstToCandidateMap &InstToCandidate) {
10671067
InstToCandidateMap LeafInstToCandidate;
1068-
SmallSet<Candidate *, 32> NotLeafCandidates;
1068+
CandidatePtrSet NotLeafCandidates;
10691069

1070-
for (Candidate *C : Candidates) {
1070+
for (const auto &C : Candidates) {
10711071
PrintDump(VerbosityLevel::High, "Finding leaf candidates... Checking:\n");
10721072
for (Instruction *I : *C) {
10731073
PrintInstructionDump(VerbosityLevel::High, I);
@@ -1081,7 +1081,7 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
10811081
continue;
10821082

10831083
if (InstToCandidate.count(Op)) {
1084-
Candidate *OpCandidate = InstToCandidate[Op];
1084+
const auto &OpCandidate = InstToCandidate[Op];
10851085
if (OpCandidate != C) {
10861086
PrintDump(VerbosityLevel::High, "Operand uses the current candidate, so is not a leaf:\n");
10871087
PrintInstructionDump(VerbosityLevel::High, Op);
@@ -1091,7 +1091,7 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
10911091
}
10921092
}
10931093
}
1094-
for (Candidate *C : Candidates) {
1094+
for (const auto &C : Candidates) {
10951095
if (NotLeafCandidates.count(C))
10961096
continue;
10971097

@@ -1111,8 +1111,8 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
11111111
bool Changed = false;
11121112

11131113
CandidatePtrVec SinkedCandidatesPtrs;
1114-
for (auto CI = SinkedCandidates.begin(), CE = SinkedCandidates.end(); CI != CE; CI++) {
1115-
Candidate *C = CI->get();
1114+
for (auto *CI = SinkedCandidates.begin(), *CE = SinkedCandidates.end(); CI != CE; CI++) {
1115+
const auto &C = *CI;
11161116
if (C->TgtBB == BB)
11171117
SinkedCandidatesPtrs.push_back(C);
11181118
}
@@ -1187,7 +1187,7 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
11871187
continue;
11881188

11891189
Changed = true;
1190-
SinkCandidates.push_back(std::make_unique<Candidate>(I, TgtBB, Worthiness, I->getNextNode()));
1190+
SinkCandidates.push_back(std::make_shared<Candidate>(I, TgtBB, Worthiness, I->getNextNode()));
11911191
continue;
11921192
}
11931193

@@ -1209,15 +1209,16 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
12091209
InstToCandidateMap CurrentInstToCandidate;
12101210

12111211
// Candidate ownership:
1212-
// Unique pointers are created in CurrentSinkCandidates on every iteration.
1213-
// Then they are moved to ToSink collection to be sinked (done in refineLoopSinkCandidates).
1214-
// Then they are moved to SinkedCandidates within iteration if they are actually sinked.
1215-
// The actually sinked Candidates have therefore live time until the end ot loopSink function.
1216-
1217-
// CurrentInstToCandidate and InstToCandidate are maps Instruction->Candidate *
1212+
// Shared pointers are created in CurrentSinkCandidates on every iteration.
1213+
// Then they are put in ToSink collection to be sinked (done in refineLoopSinkCandidates).
1214+
// Then they are put in SinkedCandidates within iteration if they are actually sinked.
1215+
// The actually sinked Candidates have therefore lifetime until the end ot loopSink function.
1216+
//
1217+
// CurrentInstToCandidate and InstToCandidate are maps Instruction->std::shared_ptr<Candidate>
1218+
//
1219+
// It's assumed that using std::shared_ptr we will successfully ensure only needed Candidates
1220+
// will remain.
12181221

1219-
// It's assumed the pointers are never invalidated, because the Candidate object is created
1220-
// via make_unique and is not relocated and destroyed until the end of the function
12211222

12221223
InstSet SkipInstructions;
12231224

@@ -1270,7 +1271,7 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
12701271
PrintInstructionDump(VerbosityLevel::Medium, I);
12711272

12721273
CurrentSinkCandidates.push_back(
1273-
std::make_unique<Candidate>(I, I->getParent(), LoopSinkWorthiness::IntraLoopSink, I->getNextNode()));
1274+
std::make_shared<Candidate>(I, I->getParent(), LoopSinkWorthiness::IntraLoopSink, I->getNextNode()));
12741275
Found2dBlockReads = true;
12751276
}
12761277

@@ -1317,19 +1318,18 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
13171318
if (C->Worthiness == LoopSinkWorthiness::Sink || C->Worthiness == LoopSinkWorthiness::IntraLoopSink) {
13181319
IGC_ASSERT(C->size() > 0);
13191320

1320-
SinkedCandidates.push_back(std::move(C));
1321-
Candidate *SC = SinkedCandidates.back().get();
1321+
SinkedCandidates.push_back(C);
13221322

1323-
bool SinkFromPH = SC->Worthiness == LoopSinkWorthiness::Sink;
1324-
Instruction *InsertPoint = SinkFromPH ? &*SC->TgtBB->getFirstInsertionPt() : SC->first()->getNextNode();
1323+
bool SinkFromPH = C->Worthiness == LoopSinkWorthiness::Sink;
1324+
Instruction *InsertPoint = SinkFromPH ? &*(C->TgtBB->getFirstInsertionPt()) : C->first()->getNextNode();
13251325

1326-
for (Instruction *I : *SC) {
1326+
for (Instruction *I : *C) {
13271327
PrintDump(VerbosityLevel::Medium,
13281328
(SinkFromPH ? "Sinking instruction:\n" : "Scheduling instruction for local sink:\n"));
13291329
PrintInstructionDump(VerbosityLevel::Medium, I);
13301330

1331-
CurrentInstToCandidate[I] = SC;
1332-
InstToCandidate[I] = SC;
1331+
CurrentInstToCandidate[I] = C;
1332+
InstToCandidate[I] = C;
13331333

13341334
I->moveBefore(InsertPoint);
13351335
InsertPoint = I;
@@ -1340,8 +1340,8 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
13401340
}
13411341
}
13421342

1343-
UndoBlkSet.insert(SC->UndoPos->getParent());
1344-
LocalBlkSet.insert(SC->TgtBB);
1343+
UndoBlkSet.insert(C->UndoPos->getParent());
1344+
LocalBlkSet.insert(C->TgtBB);
13451345

13461346
PrintDump(VerbosityLevel::Medium, "\n");
13471347
IterChanged = true;
@@ -1503,7 +1503,7 @@ bool CodeLoopSinking::loopSink(Loop *L, LoopSinkMode Mode) {
15031503
// We decided we don't rollback, change the names of the instructions in IR
15041504
for (auto &Pair : InstToCandidate) {
15051505
Instruction *I = Pair.first;
1506-
Candidate *C = Pair.second;
1506+
const auto &C = Pair.second;
15071507
if (I->getType()->isVoidTy())
15081508
continue;
15091509
std::string Prefix = C->Worthiness == LoopSinkWorthiness::IntraLoopSink ? "sched" : "sink";
@@ -1775,7 +1775,7 @@ bool CodeLoopSinking::tryCreate2dBlockReadGroupSinkingCandidate(Instruction *I,
17751775
if (IGC_IS_FLAG_ENABLED(LoopSinkCoarserLoadsRescheduling)) {
17761776
if (allUsesAreDominatedByRemainingUses(CurrentCandidateInsts, RemainingCandidateInsts)) {
17771777
NCandidates++;
1778-
SinkCandidates.push_back(std::make_unique<Candidate>(CurrentCandidateInsts, TgtBB, Worthiness,
1778+
SinkCandidates.push_back(std::make_shared<Candidate>(CurrentCandidateInsts, TgtBB, Worthiness,
17791779
CurrentCandidateInsts[0]->getNextNode()));
17801780
CurrentCandidateInsts.clear();
17811781
}
@@ -1823,7 +1823,7 @@ bool CodeLoopSinking::tryCreate2dBlockReadGroupSinkingCandidate(Instruction *I,
18231823

18241824
assertOneLoad(CurrentCandidateInsts);
18251825
NCandidates++;
1826-
SinkCandidates.push_back(std::make_unique<Candidate>(CurrentCandidateInsts, TgtBB, Worthiness,
1826+
SinkCandidates.push_back(std::make_shared<Candidate>(CurrentCandidateInsts, TgtBB, Worthiness,
18271827
CurrentCandidateInsts[0]->getNextNode()));
18281828
CurrentCandidateInsts.clear();
18291829
}
@@ -1839,7 +1839,7 @@ bool CodeLoopSinking::tryCreate2dBlockReadGroupSinkingCandidate(Instruction *I,
18391839
}
18401840
NCandidates++;
18411841
SinkCandidates.push_back(
1842-
std::make_unique<Candidate>(CurrentCandidateInsts, TgtBB, Worthiness, CurrentCandidateInsts[0]->getNextNode()));
1842+
std::make_shared<Candidate>(CurrentCandidateInsts, TgtBB, Worthiness, CurrentCandidateInsts[0]->getNextNode()));
18431843
}
18441844

18451845
PrintDump(VerbosityLevel::Medium, "Successfully created " << NCandidates << " candidates.\n");
@@ -1983,8 +1983,7 @@ bool CodeLoopSinking::tryCreateShufflePatternCandidates(BasicBlock *BB, Loop *L,
19831983
}
19841984

19851985
DenseMap<InsertElementInst *, InstSet> DestVecToShuffleInst;
1986-
CandidateVec ShuffleCandidates;
1987-
DenseMap<Instruction *, Candidate *> ShuffleInstToCandidate;
1986+
InstToCandidateMap ShuffleInstToCandidate;
19881987

19891988
for (auto &VecIEs : SourceVectors) {
19901989
DestVecToShuffleInst.clear();
@@ -2028,12 +2027,12 @@ bool CodeLoopSinking::tryCreateShufflePatternCandidates(BasicBlock *BB, Loop *L,
20282027
PrintDump(VerbosityLevel::Medium, "DestVector used in the loop:\n");
20292028
PrintInstructionDump(VerbosityLevel::Medium, DestVec);
20302029

2031-
ShuffleCandidates.push_back(std::make_unique<Candidate>(
2032-
InstrVec{}, TgtBB, SinkFromPH ? LoopSinkWorthiness::Sink : LoopSinkWorthiness::IntraLoopSink, nullptr));
2030+
auto C = std::make_shared<Candidate>(
2031+
InstrVec{}, TgtBB, SinkFromPH ? LoopSinkWorthiness::Sink : LoopSinkWorthiness::IntraLoopSink, nullptr);
20332032
Changed = true;
20342033

20352034
for (Instruction *I : ShuffleInst) {
2036-
ShuffleInstToCandidate[I] = ShuffleCandidates.back().get();
2035+
ShuffleInstToCandidate[I] = C;
20372036
}
20382037
}
20392038
}
@@ -2047,7 +2046,7 @@ bool CodeLoopSinking::tryCreateShufflePatternCandidates(BasicBlock *BB, Loop *L,
20472046
Instruction *I = &*IB;
20482047

20492048
if (ShuffleInstToCandidate.count(I)) {
2050-
Candidate *C = ShuffleInstToCandidate[I];
2049+
auto &C = ShuffleInstToCandidate[I];
20512050
if (C->size() == 0) {
20522051
C->UndoPos = I->getNextNode();
20532052
ShuffleCandidatesOrdered.push_back(C);
@@ -2058,8 +2057,8 @@ bool CodeLoopSinking::tryCreateShufflePatternCandidates(BasicBlock *BB, Loop *L,
20582057
}
20592058

20602059
// Add the candidates to the main list
2061-
for (auto *C : ShuffleCandidatesOrdered) {
2062-
SinkCandidates.push_back(std::make_unique<Candidate>(*C));
2060+
for (const auto &C : ShuffleCandidatesOrdered) {
2061+
SinkCandidates.push_back(C);
20632062
}
20642063
return Changed;
20652064
}
@@ -2276,7 +2275,7 @@ CodeLoopSinking::CandidateVec CodeLoopSinking::refineLoopSinkCandidates(Candidat
22762275
InstSet &LoadChains, Loop *L) {
22772276
struct OperandUseGroup {
22782277
SmallPtrSet<Value *, 4> Operands;
2279-
SmallVector<std::unique_ptr<Candidate> *, 16> Users;
2278+
SmallVector<std::shared_ptr<Candidate>, 16> Users;
22802279

22812280
void print(raw_ostream &OS) {
22822281
OS << "OUG " << Operands.size() << " -> " << Users.size() << "\n";
@@ -2289,7 +2288,7 @@ CodeLoopSinking::CandidateVec CodeLoopSinking::refineLoopSinkCandidates(Candidat
22892288
OS << " Users:\n";
22902289
for (auto &C : Users) {
22912290
OS << " ";
2292-
(*C)->print(OS);
2291+
C->print(OS);
22932292
OS << "\n";
22942293
}
22952294
}
@@ -2358,8 +2357,8 @@ CodeLoopSinking::CandidateVec CodeLoopSinking::refineLoopSinkCandidates(Candidat
23582357
};
23592358

23602359
auto allUsersAreLoadChains = [&](OperandUseGroup &OUG) {
2361-
return std::all_of(OUG.Users.begin(), OUG.Users.end(), [&](std::unique_ptr<Candidate> *C) {
2362-
return std::all_of((*C)->begin(), (*C)->end(), [&](Instruction *I) { return isLoadChain(I, LoadChains); });
2360+
return std::all_of(OUG.Users.begin(), OUG.Users.end(), [&](std::shared_ptr<Candidate> C) {
2361+
return std::all_of(C->begin(), C->end(), [&](Instruction *I) { return isLoadChain(I, LoadChains); });
23632362
});
23642363
};
23652364

@@ -2378,8 +2377,8 @@ CodeLoopSinking::CandidateVec CodeLoopSinking::refineLoopSinkCandidates(Candidat
23782377
}
23792378

23802379
bool AllUsersAreUniform = true;
2381-
for (auto &C : OUG.Users) {
2382-
for (Value *V : **C) {
2380+
for (const auto &C : OUG.Users) {
2381+
for (Value *V : *C) {
23832382
if (!V->hasNUsesOrMore(1))
23842383
continue;
23852384
if (!isUsedOnlyInLoop(V, L))
@@ -2449,9 +2448,9 @@ CodeLoopSinking::CandidateVec CodeLoopSinking::refineLoopSinkCandidates(Candidat
24492448

24502449
CandidateVec ToSink;
24512450

2452-
for (auto &C : SinkCandidates) {
2451+
for (const auto &C : SinkCandidates) {
24532452
if (C->Worthiness == LoopSinkWorthiness::Sink || C->Worthiness == LoopSinkWorthiness::IntraLoopSink) {
2454-
ToSink.push_back(std::move(C));
2453+
ToSink.push_back(C);
24552454
continue;
24562455
}
24572456

@@ -2465,9 +2464,9 @@ CodeLoopSinking::CandidateVec CodeLoopSinking::refineLoopSinkCandidates(Candidat
24652464
});
24662465

24672466
if (it != InstUseInfo.end())
2468-
it->Users.push_back(&C);
2467+
it->Users.push_back(C);
24692468
else
2470-
InstUseInfo.push_back(OperandUseGroup{CandidateOperands, {&C}});
2469+
InstUseInfo.push_back(OperandUseGroup{CandidateOperands, {C}});
24712470
}
24722471

24732472
// Check if it's beneficial to sink every OUG
@@ -2480,8 +2479,8 @@ CodeLoopSinking::CandidateVec CodeLoopSinking::refineLoopSinkCandidates(Candidat
24802479
continue;
24812480
PrintDump(VerbosityLevel::Medium, ">> Beneficial to sink.\n\n");
24822481
for (auto &C : OUG.Users) {
2483-
(*C)->Worthiness = LoopSinkWorthiness::Sink;
2484-
ToSink.push_back(std::move(*C));
2482+
C->Worthiness = LoopSinkWorthiness::Sink;
2483+
ToSink.push_back(C);
24852484
}
24862485
}
24872486

@@ -2635,7 +2634,7 @@ bool CodeLoopSinking::localSink(BasicBlock *BB, InstToCandidateMap &InstToCandid
26352634
PrintDump(VerbosityLevel::Medium, "Found candidate to local sink:\n");
26362635
PrintInstructionDump(VerbosityLevel::Medium, Def);
26372636

2638-
Candidate *C = Cit->second;
2637+
const auto &C = Cit->second;
26392638

26402639
IGC_ASSERT(C->size() > 0);
26412640
Instruction *MainInst = C->first();

IGC/Compiler/CISACodeGen/CodeSinking.hpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,7 @@ class CodeLoopSinking : public llvm::FunctionPass {
150150
llvm::Instruction *UndoPos)
151151
: Instructions(InstrVec{Instruction}), TgtBB(TgtBB), Worthiness(Worthiness), UndoPos(UndoPos) {}
152152

153-
Candidate(const Candidate &Other)
154-
: Instructions(Other.Instructions), TgtBB(Other.TgtBB), Worthiness(Other.Worthiness), UndoPos(Other.UndoPos) {}
155-
153+
Candidate(const Candidate &Other) = delete;
156154
Candidate &operator=(const Candidate &) = delete;
157155

158156
InstrVec Instructions;
@@ -200,10 +198,10 @@ class CodeLoopSinking : public llvm::FunctionPass {
200198
}
201199
};
202200

203-
using CandidateVec = llvm::SmallVector<std::unique_ptr<Candidate>, 64>;
204-
using CandidatePtrVec = llvm::SmallVector<Candidate *, 64>;
205-
using CandidatePtrSet = llvm::DenseSet<Candidate *>;
206-
using InstToCandidateMap = llvm::MapVector<Instruction *, Candidate *>;
201+
using CandidateVec = llvm::SmallVector<std::shared_ptr<Candidate>, 64>;
202+
using CandidatePtrVec = llvm::SmallVector<std::shared_ptr<Candidate>, 64>;
203+
using CandidatePtrSet = llvm::SmallSet<std::shared_ptr<Candidate>, 32>;
204+
using InstToCandidateMap = llvm::MapVector<Instruction *, std::shared_ptr<Candidate>>;
207205

208206
/// sinking
209207
bool loopSink(llvm::Function &F);

IGC/Compiler/CISACodeGen/LowerGEPForPrivMem.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ class SOALayoutChecker : public llvm::InstVisitor<SOALayoutChecker, bool> {
7373
SOALayoutChecker(llvm::AllocaInst &allocaToCheck, bool isOCL, bool mismatchedWidthsSupport=false);
7474
SOALayoutChecker() = delete;
7575
~SOALayoutChecker() = default;
76-
SOALayoutChecker(SOALayoutChecker &) = delete;
76+
SOALayoutChecker(const SOALayoutChecker &) = delete;
77+
SOALayoutChecker operator=(const SOALayoutChecker &) = delete;
7778

7879
SOALayoutInfo getOrGatherInfo();
7980

IGC/Compiler/CISACodeGen/MemOpt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,9 @@ class OverflowingAdditiveOperator : public Operator {
17841784
};
17851785

17861786
class OrOperator : public ConcreteOperator<BinaryOperator, Instruction::Or> {
1787+
OrOperator() = delete;
1788+
OrOperator(const OrOperator &) = delete;
1789+
OrOperator operator=(const OrOperator &) = delete;
17871790
~OrOperator() = delete;
17881791
};
17891792
class BitCastOperator : public ConcreteOperator<Operator, Instruction::BitCast> {

IGC/Compiler/CISACodeGen/SLMConstProp.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class SymProd {
3838
public:
3939
llvm::SmallVector<const llvm::Value *, 2> Prod;
4040

41-
SymProd() {}
42-
SymProd(const SymProd &P) : Prod(P.Prod) {}
41+
SymProd() = default;
42+
SymProd(const SymProd &P) = default;
4343

4444
SymProd &operator=(const SymProd &P) = delete;
4545
};

IGC/Compiler/CISACodeGen/SinkCommonOffsetFromGEP.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static bool sinkCommonOffsetForGroup(const CommonBaseGroup &Group) {
349349
BasicBlock *BB = IT.first;
350350
Type *PtrOperandTy = IT.second.first.first;
351351
Value *PtrOperand = IT.second.first.second;
352-
auto BaseIndices = IT.second.second;
352+
const auto &BaseIndices = IT.second.second;
353353

354354
Value *NewPointer = PtrOperand;
355355
if (NewPointer == nullptr)

IGC/Compiler/CISACodeGen/SplitLoads.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ struct Config {
8484

8585
Config(const Config &) = delete;
8686
Config(Config &&) = delete;
87+
Config operator=(const Config &) = delete;
88+
Config operator=(Config &&) = delete;
8789

8890
/// Value of `SIMD` as reported by metadata.
8991
unsigned SIMD() const { return actualSimd ? actualSimd : defaultSimd; }

IGC/Compiler/MetaDataApi/IGCMetaDataHelper.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ void IGCMetaDataHelper::removeFunction(MetaDataUtils &mdUtils, ModuleMetaData &M
6565
auto &FuncMD = MD.FuncMD;
6666
auto loc = FuncMD.find(Func);
6767
if (loc != FuncMD.end()) {
68-
auto funcInfo = loc->second;
6968
FuncMD.erase(Func);
7069
}
7170
}

0 commit comments

Comments
 (0)