Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 112db35

Browse files
committed
More updates
1 parent 0841e88 commit 112db35

File tree

8 files changed

+194
-110
lines changed

8 files changed

+194
-110
lines changed

benchmark/include/map_benchmark.hpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@
1212
#include <random>
1313
#include <unordered_map>
1414

15-
template <typename K, typename V>
16-
using amap =
17-
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>,
18-
std::equal_to<K>,
19-
LinAlg::BumpPtrVector<std::pair<K, V>>>;
20-
2115
template <typename D>
2216
void InsertLookup2(std::mt19937_64 &mt, D &map, uint64_t mask) {
2317
for (uint64_t i = 0; i < 256; ++i) {
@@ -65,7 +59,7 @@ static void BM_BumpMapInsertErase(benchmark::State &state) {
6559
uint64_t mask = ((1ull << state.range(0)) - 1) << 3ull;
6660
std::mt19937_64 mt;
6761
for (auto b : state) {
68-
amap<void *, uint64_t> map{WBumpAlloc<std::pair<void *, uint64_t>>(alloc)};
62+
amap<void *, uint64_t> map{alloc};
6963
InsertErase(mt, map, mask);
7064
alloc.reset();
7165
}
@@ -113,7 +107,7 @@ static void BM_BumpMapInsertLookup(benchmark::State &state) {
113107
uint64_t mask = ((1ull << state.range(0)) - 1) << 3ull;
114108
std::mt19937_64 mt;
115109
for (auto b : state) {
116-
amap<void *, uint64_t> map{WBumpAlloc<std::pair<void *, uint64_t>>(alloc)};
110+
amap<void *, uint64_t> map{alloc};
117111
InsertLookup2(mt, map, mask);
118112
alloc.reset();
119113
}
@@ -161,7 +155,7 @@ static void BM_BumpMapInsertLookup3(benchmark::State &state) {
161155
uint64_t mask = ((1ull << state.range(0)) - 1) << 3ull;
162156
std::mt19937_64 mt;
163157
for (auto b : state) {
164-
amap<void *, uint64_t> map{WBumpAlloc<std::pair<void *, uint64_t>>(alloc)};
158+
amap<void *, uint64_t> map{alloc};
165159
InsertLookup3(mt, map, mask);
166160
alloc.reset();
167161
}
@@ -213,7 +207,7 @@ BENCHMARK(BM_llvmSmallDenseMapSeq)->RangeMultiplier(2)->Range(1 << 2, 1 << 10);
213207
static void BM_BumpMapSeq(benchmark::State &state) {
214208
BumpAlloc<> alloc;
215209
for (auto b : state) {
216-
amap<void *, uint64_t> map{WBumpAlloc<std::pair<void *, uint64_t>>(alloc)};
210+
amap<void *, uint64_t> map{alloc};
217211
for (uint64_t i = 1; i <= uint64_t(state.range(0)); ++i)
218212
map[reinterpret_cast<void *>(8 * i)] = i;
219213
for (uint64_t i = 1; i <= uint64_t(state.range(0)); ++i)

include/Containers/BumpMapSet.hpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
#pragma once
22
#include "Math/BumpVector.hpp"
3+
#include "Utilities/Allocators.hpp"
34
#include <ankerl/unordered_dense.h>
45

56
template <typename K, typename V>
6-
using amap =
7-
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>,
8-
std::equal_to<K>,
9-
LinAlg::BumpPtrVector<std::pair<K, V>>>;
7+
struct amap
8+
: ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>,
9+
std::equal_to<K>,
10+
LinAlg::BumpPtrVector<std::pair<K, V>>> {
11+
using Base =
12+
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>,
13+
std::equal_to<K>,
14+
LinAlg::BumpPtrVector<std::pair<K, V>>>;
15+
amap(BumpAlloc<> &alloc) : Base{WBumpAlloc<std::pair<K, V>>(alloc)} {}
16+
};
1017
template <typename K>
11-
using aset = ankerl::unordered_dense::set<K, ankerl::unordered_dense::hash<K>,
12-
std::equal_to<K>,
13-
LinAlg::BumpPtrVector<K>>;
18+
struct aset
19+
: ankerl::unordered_dense::set<K, ankerl::unordered_dense::hash<K>,
20+
std::equal_to<K>, LinAlg::BumpPtrVector<K>> {
21+
using Base =
22+
ankerl::unordered_dense::set<K, ankerl::unordered_dense::hash<K>,
23+
std::equal_to<K>, LinAlg::BumpPtrVector<K>>;
24+
aset(BumpAlloc<> &alloc) : Base{WBumpAlloc<K>(alloc)} {}
25+
};

include/Instruction.hpp

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
#include "./Address.hpp"
44
#include "./Predicate.hpp"
5+
#include "Containers/BumpMapSet.hpp"
6+
#include "Math/BumpVector.hpp"
7+
#include "Utilities/Allocators.hpp"
58
#include <algorithm>
69
#include <concepts>
710
#include <cstddef>
@@ -32,31 +35,30 @@
3235
#include <utility>
3336
#include <variant>
3437

35-
auto containsCycle(const llvm::Instruction *,
36-
llvm::SmallPtrSet<llvm::Instruction const *, 8> &,
38+
auto containsCycle(const llvm::Instruction *, aset<llvm::Instruction const *> &,
3739
const llvm::Value *) -> bool;
38-
inline auto
39-
containsCycleCore(const llvm::Instruction *J,
40-
llvm::SmallPtrSet<llvm::Instruction const *, 8> &visited,
41-
const llvm::Instruction *K) -> bool {
40+
inline auto containsCycleCore(const llvm::Instruction *J,
41+
aset<llvm::Instruction const *> &visited,
42+
const llvm::Instruction *K) -> bool {
4243
for (const llvm::Use &op : K->operands())
4344
if (containsCycle(J, visited, op.get())) return true;
4445
return false;
4546
}
46-
inline auto
47-
containsCycle(const llvm::Instruction *J,
48-
llvm::SmallPtrSet<llvm::Instruction const *, 8> &visited,
49-
const llvm::Value *V) -> bool {
47+
inline auto containsCycle(const llvm::Instruction *J,
48+
aset<llvm::Instruction const *> &visited,
49+
const llvm::Value *V) -> bool {
5050
const auto *S = llvm::dyn_cast<llvm::Instruction>(V);
5151
if (S == J) return true;
5252
if ((!S) || (visited.count(S))) return false;
5353
visited.insert(S);
5454
return containsCycleCore(J, visited, S);
5555
}
5656

57-
inline auto containsCycle(llvm::Instruction const *S) -> bool {
57+
inline auto containsCycle(BumpAlloc<> &alloc, llvm::Instruction const *S)
58+
-> bool {
5859
// don't get trapped in a different cycle
59-
llvm::SmallPtrSet<llvm::Instruction const *, 8> visited;
60+
auto p = alloc.scope();
61+
aset<llvm::Instruction const *> visited{alloc};
6062
return containsCycleCore(S, visited, S);
6163
}
6264

@@ -156,9 +158,9 @@ struct Instruction {
156158
[[no_unique_address]] Predicate::Set predicates;
157159
[[no_unique_address]] llvm::MutableArrayRef<Instruction *> operands;
158160
// [[no_unique_address]] llvm::SmallVector<Instruction *> users;
159-
[[no_unique_address]] llvm::SmallPtrSet<Instruction *, 8> users;
161+
[[no_unique_address]] aset<Instruction *> users;
160162
/// costs[i] == cost for vector-width 2^i
161-
[[no_unique_address]] llvm::SmallVector<RecipThroughputLatency> costs;
163+
[[no_unique_address]] LinAlg::BumpPtrVector<RecipThroughputLatency> costs;
162164

163165
void setOperands(llvm::MutableArrayRef<Instruction *> ops) {
164166
operands = ops;
@@ -229,9 +231,7 @@ struct Instruction {
229231
[[nodiscard]] auto getOperand(size_t i) const -> Instruction * {
230232
return operands[i];
231233
}
232-
[[nodiscard]] auto getUsers() -> llvm::SmallPtrSetImpl<Instruction *> & {
233-
return users;
234-
}
234+
[[nodiscard]] auto getUsers() -> aset<Instruction *> & { return users; }
235235
[[nodiscard]] auto getNumOperands() const -> size_t {
236236
return operands.size();
237237
}
@@ -283,11 +283,13 @@ struct Instruction {
283283
// type(type) {
284284
// // this->TTI = TTI;
285285
// }
286-
Instruction(Intrinsic idt, llvm::Type *typ) : idtf(idt), type(typ) {}
286+
Instruction(BumpAlloc<> &alloc, Intrinsic idt, llvm::Type *typ)
287+
: idtf(idt), type(typ), predicates(alloc), users(alloc), costs(alloc) {}
287288
// Instruction(UniqueIdentifier uid)
288289
// : id(std::get<0>(uid)), operands(std::get<1>(uid)) {}
289-
Instruction(UniqueIdentifier uid, llvm::Type *typ)
290-
: idtf(std::get<0>(uid)), type(typ), operands(std::get<1>(uid)) {}
290+
Instruction(BumpAlloc<> &alloc, UniqueIdentifier uid, llvm::Type *typ)
291+
: idtf(std::get<0>(uid)), type(typ), predicates(alloc),
292+
operands(std::get<1>(uid)), users(alloc), costs(alloc) {}
291293
struct Cache {
292294
[[no_unique_address]] llvm::DenseMap<llvm::Value *, Instruction *>
293295
llvmToInternalMap;
@@ -346,7 +348,7 @@ struct Instruction {
346348
}
347349
auto createInstruction(BumpAlloc<> &alloc, UniqueIdentifier uid,
348350
llvm::Type *typ) -> Instruction * {
349-
auto *i = new (alloc) Instruction(uid, typ);
351+
auto *i = new (alloc) Instruction(alloc, uid, typ);
350352
for (auto *op : i->operands) op->users.insert(i);
351353
argMap.insert({uid, i});
352354
return i;
@@ -427,7 +429,7 @@ struct Instruction {
427429
UniqueIdentifier uid{Identifier(c), {}};
428430
auto argMatch = argMap.find(uid);
429431
if (argMatch != argMap.end()) return argMatch->second;
430-
return new (alloc) Instruction(uid, typ);
432+
return new (alloc) Instruction(alloc, uid, typ);
431433
}
432434
auto getConstant(BumpAlloc<> &alloc, llvm::Type *typ, int64_t c)
433435
-> Instruction * {
@@ -589,7 +591,7 @@ struct Instruction {
589591
static auto createIsolated(BumpAlloc<> &alloc, llvm::Instruction *instr)
590592
-> Instruction * {
591593
Intrinsic id{instr};
592-
auto *i = new (alloc) Instruction(id, instr->getType());
594+
auto *i = new (alloc) Instruction(alloc, id, instr->getType());
593595
return i;
594596
}
595597

@@ -1260,14 +1262,14 @@ struct Map {
12601262
cache.predicates.emplace_back(I);
12611263
return i;
12621264
}
1263-
void reach(llvm::BasicBlock *BB, Intersection predicate) {
1265+
void reach(BumpAlloc<> &alloc, llvm::BasicBlock *BB, Intersection predicate) {
12641266
// because we may have inserted into predMap, we need to look up
12651267
// again rather than being able to reuse anything from the
12661268
// `visit`.
12671269
if (auto f = find(BB); f != rend()) {
12681270
f->second |= predicate;
12691271
} else {
1270-
map.insert({BB, predicate});
1272+
map.insert({BB, Set{alloc, predicate}});
12711273
// map.insert(std::make_pair(BB, Set(predicate)));
12721274
}
12731275
}
@@ -1282,13 +1284,13 @@ struct Map {
12821284
// correctly
12831285
[[nodiscard]] static auto
12841286
descendBlock(BumpAlloc<> &alloc, Instruction::Cache &cache,
1285-
llvm::SmallPtrSet<llvm::BasicBlock *, 16> &visited,
1286-
Predicate::Map &predMap, llvm::BasicBlock *BBsrc,
1287-
llvm::BasicBlock *BBdst, Predicate::Intersection predicate,
1288-
llvm::BasicBlock *BBhead, llvm::Loop *L) -> Destination {
1287+
aset<llvm::BasicBlock *> &visited, Predicate::Map &predMap,
1288+
llvm::BasicBlock *BBsrc, llvm::BasicBlock *BBdst,
1289+
Predicate::Intersection predicate, llvm::BasicBlock *BBhead,
1290+
llvm::Loop *L) -> Destination {
12891291
if (BBsrc == BBdst) {
12901292
assert(!predMap.contains(BBsrc));
1291-
predMap.insert({BBsrc, predicate});
1293+
predMap.insert({BBsrc, Set{alloc, predicate}});
12921294
return Destination::Reached;
12931295
} else if (L && (!(L->contains(BBsrc)))) {
12941296
// oops, we seem to have skipped the preheader and escaped the
@@ -1320,7 +1322,7 @@ struct Map {
13201322
if (BI->isUnconditional()) {
13211323
auto rc = descendBlock(alloc, cache, visited, predMap,
13221324
BI->getSuccessor(0), BBdst, predicate, BBhead, L);
1323-
if (rc == Destination::Reached) predMap.reach(BBsrc, predicate);
1325+
if (rc == Destination::Reached) predMap.reach(alloc, BBsrc, predicate);
13241326
return rc;
13251327
}
13261328
// We have a conditional branch.
@@ -1340,7 +1342,7 @@ struct Map {
13401342
// we're now assuming that !cond
13411343
predMap.assume(
13421344
Predicate::Intersection(predInd, Predicate::Relation::False));
1343-
predMap.reach(BBsrc, predicate);
1345+
predMap.reach(alloc, BBsrc, predicate);
13441346
}
13451347
return rc1;
13461348
} else if ((rc1 == Destination::Returned) ||
@@ -1349,11 +1351,11 @@ struct Map {
13491351
// we're now assuming that cond
13501352
predMap.assume(
13511353
Predicate::Intersection(predInd, Predicate::Relation::True));
1352-
predMap.reach(BBsrc, predicate);
1354+
predMap.reach(alloc, BBsrc, predicate);
13531355
}
13541356
return rc0;
13551357
} else if (rc0 == rc1) {
1356-
if (rc0 == Destination::Reached) predMap.reach(BBsrc, predicate);
1358+
if (rc0 == Destination::Reached) predMap.reach(alloc, BBsrc, predicate);
13571359
return rc0;
13581360
} else return Destination::Unknown;
13591361
}
@@ -1364,7 +1366,7 @@ struct Map {
13641366
llvm::BasicBlock *start, llvm::BasicBlock *stop, llvm::Loop *L)
13651367
-> std::optional<Map> {
13661368
Predicate::Map pm;
1367-
llvm::SmallPtrSet<llvm::BasicBlock *, 16> visited;
1369+
aset<llvm::BasicBlock *> visited(alloc);
13681370
if (descendBlock(alloc, cache, visited, pm, start, stop, {}, start, L) ==
13691371
Destination::Reached)
13701372
return pm;
@@ -1379,9 +1381,9 @@ inline auto Instruction::Cache::getInstruction(BumpAlloc<> &alloc,
13791381
llvm::Instruction *instr)
13801382
-> Instruction * {
13811383
if (Instruction *i = completeInstruction(alloc, predMap, instr)) return i;
1382-
if (containsCycle(instr)) {
1383-
auto *i =
1384-
new (alloc) Instruction(Instruction::Intrinsic(instr), instr->getType());
1384+
if (containsCycle(alloc, instr)) {
1385+
auto *i = new (alloc)
1386+
Instruction(alloc, Instruction::Intrinsic(instr), instr->getType());
13851387
llvmToInternalMap[instr] = i;
13861388
return i;
13871389
}
@@ -1417,12 +1419,19 @@ inline auto Instruction::Cache::getInstruction(BumpAlloc<> &alloc,
14171419
-> Instruction * {
14181420

14191421
if (auto *instr = llvm::dyn_cast<llvm::Instruction>(v)) {
1420-
if (containsCycle(instr)) {
1422+
if (containsCycle(alloc, instr)) {
14211423
}
14221424
return getInstruction(alloc, predMap, instr);
14231425
}
14241426
return getInstruction(alloc, v);
14251427
}
1428+
static_assert(
1429+
std::is_trivially_destructible_v<
1430+
std::variant<std::monostate, llvm::Instruction *, llvm::ConstantInt *,
1431+
llvm::ConstantFP *, Address *>>);
1432+
static_assert(std::is_trivially_destructible_v<Predicate::Set>);
1433+
static_assert(
1434+
std::is_trivially_destructible_v<LinAlg::BumpPtrVector<Instruction *>>);
14261435
/*
14271436
struct InstructionBlock {
14281437
// we tend to heap allocate InstructionBlocks with a bump allocator,

include/LoopForest.hpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct LoopTree {
3232

3333
// in addition to requiring simplify form, we require a single exit block
3434
[[no_unique_address]] llvm::SmallVector<Predicate::Map> paths;
35-
[[no_unique_address]] AffineLoopNest<true> affineLoop;
35+
[[no_unique_address]] Optional<AffineLoopNest<true> *> affineLoop;
3636
[[no_unique_address]] Optional<LoopTree *> parentLoop{nullptr};
3737
[[no_unique_address]] llvm::SmallVector<NotNull<MemoryAccess>> memAccesses{};
3838

@@ -62,39 +62,40 @@ struct LoopTree {
6262
llvm::SmallVector<Predicate::Map> pth)
6363
: loop(nullptr), subLoops(std::move(sL)), paths(std::move(pth)) {}
6464

65-
LoopTree(llvm::Loop *L, const llvm::SCEV *BT, llvm::ScalarEvolution &SE,
66-
Predicate::Map pth)
67-
: loop(L), paths({std::move(pth)}), affineLoop(L, BT, SE) {}
65+
LoopTree(BumpAlloc<> &alloc, llvm::Loop *L, const llvm::SCEV *BT,
66+
llvm::ScalarEvolution &SE, Predicate::Map pth)
67+
: loop(L), paths({std::move(pth)}),
68+
affineLoop{AffineLoopNest<true>::construct(alloc, L, BT, SE)} {}
6869

69-
LoopTree(llvm::Loop *L, AffineLoopNest<true> aln,
70+
LoopTree(BumpAlloc<> &alloc, llvm::Loop *L, NotNull<AffineLoopNest<true>> aln,
7071
llvm::SmallVector<NotNull<LoopTree>> sL,
7172
llvm::SmallVector<Predicate::Map> pth)
7273
: loop(L), subLoops(std::move(sL)), paths(std::move(pth)),
73-
affineLoop(std::move(aln)) {
74+
affineLoop(aln->copy(alloc)) {
7475
#ifndef NDEBUG
7576
if (loop)
7677
for (auto &&chain : pth)
7778
for (auto &&pbb : chain) assert(loop->contains(pbb.first));
7879
#endif
7980
}
8081
[[nodiscard]] auto getNumLoops() const -> size_t {
81-
return affineLoop.getNumLoops();
82+
return affineLoop->getNumLoops();
8283
}
83-
8484
friend inline auto operator<<(llvm::raw_ostream &os, const LoopTree &tree)
8585
-> llvm::raw_ostream & {
86-
if (tree.loop) os << (*tree.loop) << "\n" << tree.affineLoop << "\n";
86+
if (tree.loop) os << (*tree.loop) << "\n" << *tree.affineLoop << "\n";
8787
else os << "top-level:\n";
8888
for (auto branch : tree.subLoops) os << *branch;
8989
return os << "\n";
9090
}
9191
#ifndef NDEBUG
9292
[[gnu::used]] void dump() const { llvm::errs() << *this; }
9393
#endif
94-
void addZeroLowerBounds(llvm::DenseMap<llvm::Loop *, LoopTree *> &loopMap) {
95-
affineLoop.addZeroLowerBounds();
94+
void addZeroLowerBounds(BumpAlloc<> &alloc,
95+
llvm::DenseMap<llvm::Loop *, LoopTree *> &loopMap) {
96+
affineLoop->addZeroLowerBounds(alloc);
9697
for (auto tree : subLoops) {
97-
tree->addZeroLowerBounds(loopMap);
98+
tree->addZeroLowerBounds(alloc, loopMap);
9899
tree->parentLoop = this;
99100
}
100101
if (loop) loopMap.insert(std::make_pair(loop, this));

0 commit comments

Comments
 (0)