Mercurial > hg > CbC > CbC_llvm
comparison lld/COFF/MarkLive.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 0572611fdcc8 |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 //===- MarkLive.cpp -------------------------------------------------------===// | |
2 // | |
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
4 // See https://llvm.org/LICENSE.txt for license information. | |
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
6 // | |
7 //===----------------------------------------------------------------------===// | |
8 | |
9 #include "Chunks.h" | |
10 #include "Symbols.h" | |
11 #include "lld/Common/Timer.h" | |
12 #include "llvm/ADT/STLExtras.h" | |
13 #include <vector> | |
14 | |
15 namespace lld { | |
16 namespace coff { | |
17 | |
18 static Timer gctimer("GC", Timer::root()); | |
19 | |
20 // Set live bit on for each reachable chunk. Unmarked (unreachable) | |
21 // COMDAT chunks will be ignored by Writer, so they will be excluded | |
22 // from the final output. | |
23 void markLive(ArrayRef<Chunk *> chunks) { | |
24 ScopedTimer t(gctimer); | |
25 | |
26 // We build up a worklist of sections which have been marked as live. We only | |
27 // push into the worklist when we discover an unmarked section, and we mark | |
28 // as we push, so sections never appear twice in the list. | |
29 SmallVector<SectionChunk *, 256> worklist; | |
30 | |
31 // COMDAT section chunks are dead by default. Add non-COMDAT chunks. | |
32 for (Chunk *c : chunks) | |
33 if (auto *sc = dyn_cast<SectionChunk>(c)) | |
34 if (sc->live) | |
35 worklist.push_back(sc); | |
36 | |
37 auto enqueue = [&](SectionChunk *c) { | |
38 if (c->live) | |
39 return; | |
40 c->live = true; | |
41 worklist.push_back(c); | |
42 }; | |
43 | |
44 auto addSym = [&](Symbol *b) { | |
45 if (auto *sym = dyn_cast<DefinedRegular>(b)) | |
46 enqueue(sym->getChunk()); | |
47 else if (auto *sym = dyn_cast<DefinedImportData>(b)) | |
48 sym->file->live = true; | |
49 else if (auto *sym = dyn_cast<DefinedImportThunk>(b)) | |
50 sym->wrappedSym->file->live = sym->wrappedSym->file->thunkLive = true; | |
51 }; | |
52 | |
53 // Add GC root chunks. | |
54 for (Symbol *b : config->gcroot) | |
55 addSym(b); | |
56 | |
57 while (!worklist.empty()) { | |
58 SectionChunk *sc = worklist.pop_back_val(); | |
59 assert(sc->live && "We mark as live when pushing onto the worklist!"); | |
60 | |
61 // Mark all symbols listed in the relocation table for this section. | |
62 for (Symbol *b : sc->symbols()) | |
63 if (b) | |
64 addSym(b); | |
65 | |
66 // Mark associative sections if any. | |
67 for (SectionChunk &c : sc->children()) | |
68 enqueue(&c); | |
69 } | |
70 } | |
71 | |
72 } | |
73 } |