Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: lib/Bitcode/NaCl/Analysis/AbbrevTrieNode.cpp

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/Bitcode/Makefile ('k') | lib/Bitcode/NaCl/Analysis/CMakeLists.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- AbbrevTrieNode.cpp ------------------------------------------------===//
2 // Implements abbreviation lookup tries.
3 //
4 // The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #include "llvm/Bitcode/NaCl/AbbrevTrieNode.h"
12 #include "llvm/Bitcode/NaCl/NaClBitcodeValueDist.h"
13
14 using namespace llvm;
15
16 void AbbrevTrieNode::GetSuccessorLabels(SuccessorLabels &Labels) const {
17 for (SuccessorMap::const_iterator
18 IndexIter = Successors.begin(), IndexIterEnd = Successors.end();
19 IndexIter != IndexIterEnd; ++IndexIter) {
20 if (const SuccessorValueMap *ValueMap = IndexIter->second) {
21 for (SuccessorValueMap::const_iterator
22 ValueIter = ValueMap->begin(), ValueIterEnd = ValueMap->end();
23 ValueIter != ValueIterEnd; ++ValueIter) {
24 Labels.push_back(std::pair<size_t, uint64_t>(IndexIter->first,
25 ValueIter->first));
26 }
27 }
28 }
29 }
30
31 AbbrevTrieNode::~AbbrevTrieNode() {
32 for (SuccessorMap::const_iterator
33 Iter = Successors.begin(), IterEnd = Successors.end();
34 Iter != IterEnd; ++Iter) {
35 if (const SuccessorValueMap *ValueMap = Iter->second) {
36 for (SuccessorValueMap::const_iterator
37 Iter = ValueMap->begin(), IterEnd = ValueMap->end();
38 Iter != IterEnd; ++Iter) {
39 delete Iter->second;
40 }
41 delete ValueMap;
42 }
43 }
44 }
45
46 void AbbrevTrieNode::Print(raw_ostream &Stream,
47 const std::string &Indent,
48 bool LocalOnly) const {
49 std::string IndentPlus(Indent);
50 IndentPlus.append(" ");
51 std::string IndentPlusPlus(IndentPlus);
52 IndentPlusPlus.append(" ");
53 if (! Abbreviations.empty()) {
54 Stream << Indent << "Abbreviations:\n";
55 for (std::set<AbbrevIndexPair>::const_iterator
56 Iter = Abbreviations.begin(), IterEnd = Abbreviations.end();
57 Iter != IterEnd; ++Iter) {
58 Stream << IndentPlus;
59 Iter->second->Print(Stream, /* AddNewline= */ false);
60 Stream << " (abbrev #" << Iter->first << ")\n";
61 }
62 }
63 if (LocalOnly) return;
64 if (!Successors.empty()) {
65 Stream << Indent << "Successor Map:\n";
66 SuccessorLabels Labels;
67 GetSuccessorLabels(Labels);
68 for (SuccessorLabels::const_iterator
69 Iter = Labels.begin(), IterEnd = Labels.end();
70 Iter != IterEnd; ++Iter) {
71 size_t Index = Iter->first;
72 if (Index == 0) {
73 Stream << IndentPlus << "Record.Code = " << Iter->second << "\n";
74 } else {
75 Stream << IndentPlus << "Record.Values[" << (Index-1)
76 << "] = " << Iter->second << "\n";
77 }
78 GetSuccessor(Iter->first, Iter->second)->Print(Stream, IndentPlusPlus);
79 }
80 }
81 }
82
83 AbbrevTrieNode *AbbrevTrieNode::
84 GetSuccessor(size_t Index, uint64_t Value) const {
85 SuccessorMap::const_iterator IndexPos = Successors.find(Index);
86 if (IndexPos != Successors.end()) {
87 if (SuccessorValueMap *ValueMap = IndexPos->second) {
88 SuccessorValueMap::iterator ValuePos = ValueMap->find(Value);
89 if (ValuePos != ValueMap->end())
90 return ValuePos->second;
91 }
92 }
93 return 0;
94 }
95
96 bool AbbrevTrieNode::Add(NaClBitCodeAbbrev *Abbrev,
97 size_t Index, size_t SkipIndex) {
98 if (Index >= Abbrev->getNumOperandInfos()) return false;
99 bool AddedNodes = false;
100
101 // Skip over matches that may match because they don't have constants
102 // in the index.
103 while (SkipIndex < Index) {
104 SuccessorMap::iterator Pos = Successors.find(SkipIndex);
105 if (Pos != Successors.end()) {
106 SuccessorValueMap *ValueMap = Pos->second;
107 for (SuccessorValueMap::const_iterator
108 Iter = ValueMap->begin(), IterEnd = ValueMap->end();
109 Iter != IterEnd; ++Iter) {
110 if (AbbrevTrieNode *Successor = Iter->second) {
111 if (Successor->Add(Abbrev, Index, SkipIndex+1))
112 AddedNodes = true;
113 }
114 }
115 }
116 ++SkipIndex;
117 }
118
119 // Now update successors for next matching constant in abbreviation.
120 for (; Index < Abbrev->GetMinRecordSize(); ++Index) {
121 const NaClBitCodeAbbrevOp &Op = Abbrev->getOperandInfo(Index);
122 if (Op.isLiteral()) {
123 if (Index == SkipIndex) {
124 // No preceeding nodes to match, add here.
125 SuccessorValueMap *ValueMap = Successors[Index];
126 if (ValueMap == 0) {
127 ValueMap = new SuccessorValueMap();
128 Successors[Index] = ValueMap;
129 }
130 AbbrevTrieNode *Successor = (*ValueMap)[Op.getValue()];
131 if (Successor == 0) {
132 Successor = new AbbrevTrieNode();
133 AddedNodes = true;
134 (*ValueMap)[Op.getValue()] = Successor;
135 }
136 if (Successor->Add(Abbrev, Index+1, Index+1))
137 AddedNodes = true;
138 } else {
139 // Need to match all possible prefixes before inserting constant.
140 if (Add(Abbrev, Index, SkipIndex))
141 AddedNodes = true;
142 }
143 return AddedNodes;
144 }
145 }
146 return AddedNodes;
147 }
148
149 void AbbrevTrieNode::Insert(AbbrevIndexPair &AbbrevPair) {
150 NaClBitCodeAbbrev *Abbrev = AbbrevPair.second;
151
152 for (std::map<size_t, SuccessorValueMap*>::iterator
153 Iter = Successors.begin(), IterEnd = Successors.end();
154 Iter != IterEnd; ++Iter) {
155 if (SuccessorValueMap *ValueMap = Iter->second) {
156 if (Iter->first < Abbrev->GetMinRecordSize()) {
157 const NaClBitCodeAbbrevOp &Op =
158 Abbrev->getOperandInfo(Iter->first);
159 if (Op.isLiteral()) {
160 uint64_t Value = Op.getValue();
161 SuccessorValueMap::iterator Pos = ValueMap->find(Value);
162 if (Pos != ValueMap->end()) {
163 if (AbbrevTrieNode *Next = Pos->second) {
164 // Found constant that will be followed, update subgraph
165 // and quit.
166 Next->Insert(AbbrevPair);
167 return;
168 }
169 }
170 } else {
171 // Not literal, so it may (or may not) be followed, depending
172 // on the value in the record that will be matched against. So
173 // add to subgraph, and here if no succeeding matching literal
174 // constants.
175 for (SuccessorValueMap::iterator
176 Iter = ValueMap->begin(), IterEnd = ValueMap->end();
177 Iter != IterEnd; ++Iter) {
178 if (AbbrevTrieNode *Next = Iter->second)
179 Next->Insert(AbbrevPair);
180 }
181 }
182 } else if (!Abbrev->IsFixedSize()) {
183 // May match array element. So add to subgraph as well as here.
184 for (SuccessorValueMap::iterator
185 Iter = ValueMap->begin(), IterEnd = ValueMap->end();
186 Iter != IterEnd; ++Iter) {
187 if (AbbrevTrieNode *Next = Iter->second)
188 Next->Insert(AbbrevPair);
189 }
190 }
191 }
192 }
193
194 // If reached, no guarantees that any edge was followed, so add
195 // to matches of this node.
196 Abbreviations.insert(AbbrevPair);
197 }
198
199 const AbbrevTrieNode *AbbrevTrieNode::
200 MatchRecord(const NaClBitcodeRecordData &Record) const {
201 for (std::map<size_t, SuccessorValueMap*>::const_iterator
202 Iter = Successors.begin(), IterEnd = Successors.end();
203 Iter != IterEnd; ++Iter) {
204 if (SuccessorValueMap *ValueMap = Iter->second) {
205 if (Iter->first <= Record.Values.size()) {
206 uint64_t Value;
207 if (Iter->first == 0)
208 Value = Record.Code;
209 else
210 Value = Record.Values[Iter->first-1];
211 SuccessorValueMap::iterator Pos = ValueMap->find(Value);
212 if (Pos != ValueMap->end()) {
213 if (AbbrevTrieNode *Next = Pos->second) {
214 return Next->MatchRecord(Record);
215 }
216 }
217 } else {
218 // Map index too big, quit.
219 break;
220 }
221 }
222 }
223
224 // If reached, no refinement found, use this node.
225 return this;
226 }
227
228 static void ComputeAbbrevRange(NaClBitCodeAbbrev *Abbrev,
229 size_t &MinIndex, size_t &MaxIndex) {
230 // Find the range of record lengths for which the abbreviation may
231 // apply. Note: To keep a limit on the number of copies, collapse all
232 // records with length > NaClValueIndexCutoff into the same bucket.
233 MinIndex = Abbrev->GetMinRecordSize();
234 if (MinIndex > NaClValueIndexCutoff) {
235 MinIndex = NaClValueIndexCutoff + 1;
236 }
237 MaxIndex = MinIndex;
238 if (!Abbrev->IsFixedSize()) {
239 MaxIndex = NaClValueIndexCutoff + 1;
240 }
241 }
242
243 // Once all nodes have been added (via calls to AddAbbrevToLookupMap),
244 // this function adds the given abbreviation pair to all possible
245 // matchxes in the lookup map.
246 static void AddAbbrevPairToLookupMap(AbbrevLookupSizeMap &LookupMap,
247 AbbrevIndexPair &AbbrevPair) {
248 size_t MinIndex, MaxIndex;
249 ComputeAbbrevRange(AbbrevPair.second, MinIndex, MaxIndex);
250 for (size_t Index = MinIndex; Index <= MaxIndex; ++Index) {
251 AbbrevTrieNode *Node = LookupMap[Index];
252 assert(Node);
253 Node->Insert(AbbrevPair);
254 }
255 }
256
257 // Adds the given abbreviation to the corresponding lookup map, constructing
258 // the map of usable lookup tries.
259 static bool AddAbbrevToLookupMap(AbbrevLookupSizeMap &LookupMap,
260 NaClBitCodeAbbrev *Abbrev) {
261 bool Added = false;
262 size_t MinIndex, MaxIndex;
263 ComputeAbbrevRange(Abbrev, MinIndex, MaxIndex);
264 for (size_t Index = MinIndex; Index <= MaxIndex; ++Index) {
265 AbbrevTrieNode *Node = LookupMap[Index];
266 if (Node == 0) {
267 Node = new AbbrevTrieNode();
268 LookupMap[Index] = Node;
269 Added = true;
270 }
271 if (Node->Add(Abbrev)) Added = true;
272 }
273 return Added;
274 }
275
276 void llvm::NaClBuildAbbrevLookupMap(
277 AbbrevLookupSizeMap &LookupMap,
278 const SmallVectorImpl<NaClBitCodeAbbrev*> &Abbrevs,
279 size_t InitialIndex) {
280 // First build nodes of trie.
281 bool FixpointFound = false;
282 while (!FixpointFound) {
283 FixpointFound = true;
284 for (size_t i = InitialIndex; i < Abbrevs.size(); ++i) {
285 if (AddAbbrevToLookupMap(LookupMap, Abbrevs[i]))
286 FixpointFound = false;
287 }
288 }
289
290 // Now populate with abbreviations that apply.
291 for (size_t i = InitialIndex; i < Abbrevs.size(); ++i) {
292 AbbrevIndexPair Pair(i, Abbrevs[i]);
293 AddAbbrevPairToLookupMap(LookupMap, Pair);
294 }
295 }
OLDNEW
« no previous file with comments | « lib/Bitcode/Makefile ('k') | lib/Bitcode/NaCl/Analysis/CMakeLists.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698