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

Side by Side Diff: src/IceOperand.cpp

Issue 1253833002: Subzero: Cleanly implement register allocation after phi lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Cleanup Created 5 years, 5 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
OLDNEW
1 //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===// 1 //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 return this; 139 return this;
140 Variable *V = new (getCurrentCfgAllocator()->Allocate<Variable>()) 140 Variable *V = new (getCurrentCfgAllocator()->Allocate<Variable>())
141 Variable(kVariable, Ty, Number); 141 Variable(kVariable, Ty, Number);
142 V->NameIndex = NameIndex; 142 V->NameIndex = NameIndex;
143 V->RegNum = RegNum; 143 V->RegNum = RegNum;
144 V->StackOffset = StackOffset; 144 V->StackOffset = StackOffset;
145 return V; 145 return V;
146 } 146 }
147 147
148 void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr, 148 void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr,
149 const CfgNode *Node, bool IsFromDef, 149 CfgNode *Node, bool IsImplicit) {
150 bool IsImplicit) {
151 (void)TrackingKind; 150 (void)TrackingKind;
152 if (MultiBlock == MBS_MultiBlock) 151 if (MultiBlock == MBS_MultiBlock)
153 return; 152 return;
154 // TODO(stichnot): If the use occurs as a source operand in the 153 // TODO(stichnot): If the use occurs as a source operand in the
155 // first instruction of the block, and its definition is in this 154 // first instruction of the block, and its definition is in this
156 // block's only predecessor, we might consider not marking this as a 155 // block's only predecessor, we might consider not marking this as a
157 // separate use. This may also apply if it's the first instruction 156 // separate use. This may also apply if it's the first instruction
158 // of the block that actually uses a Variable. 157 // of the block that actually uses a Variable.
159 assert(Node); 158 assert(Node);
160 bool MakeMulti = false; 159 bool MakeMulti = false;
161 if (IsImplicit) 160 if (IsImplicit)
162 MakeMulti = true; 161 MakeMulti = true;
163 // A phi source variable conservatively needs to be marked as 162 // A phi source variable conservatively needs to be marked as
164 // multi-block, even if its definition is in the same block. This 163 // multi-block, even if its definition is in the same block. This
165 // is because there can be additional control flow before branching 164 // is because there can be additional control flow before branching
166 // back to this node, and the variable is live throughout those 165 // back to this node, and the variable is live throughout those
167 // nodes. 166 // nodes.
168 if (!IsFromDef && Instr && llvm::isa<InstPhi>(Instr)) 167 if (Instr && llvm::isa<InstPhi>(Instr))
169 MakeMulti = true; 168 MakeMulti = true;
170 169
171 if (!MakeMulti) { 170 if (!MakeMulti) {
172 switch (MultiBlock) { 171 switch (MultiBlock) {
173 case MBS_Unknown: 172 case MBS_Unknown:
174 MultiBlock = MBS_SingleBlock; 173 MultiBlock = MBS_SingleBlock;
175 SingleUseNode = Node; 174 SingleUseNode = Node;
176 break; 175 break;
177 case MBS_SingleBlock: 176 case MBS_SingleBlock:
178 if (SingleUseNode != Node) 177 if (SingleUseNode != Node)
179 MakeMulti = true; 178 MakeMulti = true;
180 break; 179 break;
181 case MBS_MultiBlock: 180 case MBS_MultiBlock:
182 break; 181 break;
183 } 182 }
184 } 183 }
185 184
186 if (MakeMulti) { 185 if (MakeMulti) {
187 MultiBlock = MBS_MultiBlock; 186 MultiBlock = MBS_MultiBlock;
188 SingleUseNode = nullptr; 187 SingleUseNode = nullptr;
189 } 188 }
190 } 189 }
191 190
192 void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr, 191 void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr,
193 const CfgNode *Node) { 192 CfgNode *Node) {
194 // TODO(stichnot): If the definition occurs in the last instruction 193 // TODO(stichnot): If the definition occurs in the last instruction
195 // of the block, consider not marking this as a separate use. But 194 // of the block, consider not marking this as a separate use. But
196 // be careful not to omit all uses of the variable if markDef() and 195 // be careful not to omit all uses of the variable if markDef() and
197 // markUse() both use this optimization. 196 // markUse() both use this optimization.
198 assert(Node); 197 assert(Node);
199 // Verify that instructions are added in increasing order. 198 // Verify that instructions are added in increasing order.
200 #ifndef NDEBUG 199 #ifndef NDEBUG
201 if (TrackingKind == VMK_All) { 200 if (TrackingKind == VMK_All) {
202 const Inst *LastInstruction = 201 const Inst *LastInstruction =
203 Definitions.empty() ? FirstOrSingleDefinition : Definitions.back(); 202 Definitions.empty() ? FirstOrSingleDefinition : Definitions.back();
204 assert(LastInstruction == nullptr || 203 assert(LastInstruction == nullptr ||
205 Instr->getNumber() >= LastInstruction->getNumber()); 204 Instr->getNumber() >= LastInstruction->getNumber());
206 } 205 }
207 #endif 206 #endif
208 const bool IsFromDef = true; 207 constexpr bool IsImplicit = false;
209 const bool IsImplicit = false; 208 markUse(TrackingKind, Instr, Node, IsImplicit);
210 markUse(TrackingKind, Instr, Node, IsFromDef, IsImplicit);
211 if (TrackingKind == VMK_Uses) 209 if (TrackingKind == VMK_Uses)
212 return; 210 return;
213 if (FirstOrSingleDefinition == nullptr) 211 if (FirstOrSingleDefinition == nullptr)
214 FirstOrSingleDefinition = Instr; 212 FirstOrSingleDefinition = Instr;
215 else if (TrackingKind == VMK_All) 213 else if (TrackingKind == VMK_All)
216 Definitions.push_back(Instr); 214 Definitions.push_back(Instr);
217 switch (MultiDef) { 215 switch (MultiDef) {
218 case MDS_Unknown: 216 case MDS_Unknown:
219 assert(SingleDefNode == nullptr); 217 assert(SingleDefNode == nullptr);
220 MultiDef = MDS_SingleDef; 218 MultiDef = MDS_SingleDef;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 267 }
270 268
271 void VariablesMetadata::init(MetadataKind TrackingKind) { 269 void VariablesMetadata::init(MetadataKind TrackingKind) {
272 TimerMarker T(TimerStack::TT_vmetadata, Func); 270 TimerMarker T(TimerStack::TT_vmetadata, Func);
273 Kind = TrackingKind; 271 Kind = TrackingKind;
274 Metadata.clear(); 272 Metadata.clear();
275 Metadata.resize(Func->getNumVariables()); 273 Metadata.resize(Func->getNumVariables());
276 274
277 // Mark implicit args as being used in the entry node. 275 // Mark implicit args as being used in the entry node.
278 for (Variable *Var : Func->getImplicitArgs()) { 276 for (Variable *Var : Func->getImplicitArgs()) {
279 const Inst *NoInst = nullptr; 277 constexpr Inst *NoInst = nullptr;
280 const CfgNode *EntryNode = Func->getEntryNode(); 278 CfgNode *EntryNode = Func->getEntryNode();
281 const bool IsFromDef = false; 279 constexpr bool IsImplicit = true;
282 const bool IsImplicit = true; 280 Metadata[Var->getIndex()].markUse(Kind, NoInst, EntryNode, IsImplicit);
283 Metadata[Var->getIndex()].markUse(Kind, NoInst, EntryNode, IsFromDef,
284 IsImplicit);
285 } 281 }
286 282
287 for (CfgNode *Node : Func->getNodes()) 283 for (CfgNode *Node : Func->getNodes())
288 addNode(Node); 284 addNode(Node);
289 } 285 }
290 286
291 void VariablesMetadata::addNode(CfgNode *Node) { 287 void VariablesMetadata::addNode(CfgNode *Node) {
292 if (Func->getNumVariables() >= Metadata.size()) 288 if (Func->getNumVariables() >= Metadata.size())
293 Metadata.resize(Func->getNumVariables()); 289 Metadata.resize(Func->getNumVariables());
294 290
295 for (Inst &I : Node->getPhis()) { 291 for (Inst &I : Node->getPhis()) {
296 if (I.isDeleted()) 292 if (I.isDeleted())
297 continue; 293 continue;
298 if (Variable *Dest = I.getDest()) { 294 if (Variable *Dest = I.getDest()) {
299 SizeT DestNum = Dest->getIndex(); 295 SizeT DestNum = Dest->getIndex();
300 assert(DestNum < Metadata.size()); 296 assert(DestNum < Metadata.size());
301 Metadata[DestNum].markDef(Kind, &I, Node); 297 Metadata[DestNum].markDef(Kind, &I, Node);
302 } 298 }
303 for (SizeT SrcNum = 0; SrcNum < I.getSrcSize(); ++SrcNum) { 299 for (SizeT SrcNum = 0; SrcNum < I.getSrcSize(); ++SrcNum) {
304 if (const Variable *Var = llvm::dyn_cast<Variable>(I.getSrc(SrcNum))) { 300 if (const Variable *Var = llvm::dyn_cast<Variable>(I.getSrc(SrcNum))) {
305 SizeT VarNum = Var->getIndex(); 301 SizeT VarNum = Var->getIndex();
306 assert(VarNum < Metadata.size()); 302 assert(VarNum < Metadata.size());
307 const bool IsFromDef = false; 303 constexpr bool IsImplicit = false;
308 const bool IsImplicit = false; 304 Metadata[VarNum].markUse(Kind, &I, Node, IsImplicit);
309 Metadata[VarNum].markUse(Kind, &I, Node, IsFromDef, IsImplicit);
310 } 305 }
311 } 306 }
312 } 307 }
313 308
314 for (Inst &I : Node->getInsts()) { 309 for (Inst &I : Node->getInsts()) {
315 if (I.isDeleted()) 310 if (I.isDeleted())
316 continue; 311 continue;
317 // Note: The implicit definitions (and uses) from InstFakeKill are 312 // Note: The implicit definitions (and uses) from InstFakeKill are
318 // deliberately ignored. 313 // deliberately ignored.
319 if (Variable *Dest = I.getDest()) { 314 if (Variable *Dest = I.getDest()) {
320 SizeT DestNum = Dest->getIndex(); 315 SizeT DestNum = Dest->getIndex();
321 assert(DestNum < Metadata.size()); 316 assert(DestNum < Metadata.size());
322 Metadata[DestNum].markDef(Kind, &I, Node); 317 Metadata[DestNum].markDef(Kind, &I, Node);
323 } 318 }
324 for (SizeT SrcNum = 0; SrcNum < I.getSrcSize(); ++SrcNum) { 319 for (SizeT SrcNum = 0; SrcNum < I.getSrcSize(); ++SrcNum) {
325 Operand *Src = I.getSrc(SrcNum); 320 Operand *Src = I.getSrc(SrcNum);
326 SizeT NumVars = Src->getNumVars(); 321 SizeT NumVars = Src->getNumVars();
327 for (SizeT J = 0; J < NumVars; ++J) { 322 for (SizeT J = 0; J < NumVars; ++J) {
328 const Variable *Var = Src->getVar(J); 323 const Variable *Var = Src->getVar(J);
329 SizeT VarNum = Var->getIndex(); 324 SizeT VarNum = Var->getIndex();
330 assert(VarNum < Metadata.size()); 325 assert(VarNum < Metadata.size());
331 const bool IsFromDef = false; 326 constexpr bool IsImplicit = false;
332 const bool IsImplicit = false; 327 Metadata[VarNum].markUse(Kind, &I, Node, IsImplicit);
333 Metadata[VarNum].markUse(Kind, &I, Node, IsFromDef, IsImplicit);
334 } 328 }
335 } 329 }
336 } 330 }
337 } 331 }
338 332
339 bool VariablesMetadata::isMultiDef(const Variable *Var) const { 333 bool VariablesMetadata::isMultiDef(const Variable *Var) const {
340 assert(Kind != VMK_Uses); 334 assert(Kind != VMK_Uses);
341 if (Var->getIsArg()) 335 if (Var->getIsArg())
342 return false; 336 return false;
343 if (!isTracked(Var)) 337 if (!isTracked(Var))
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 369
376 const InstDefList & 370 const InstDefList &
377 VariablesMetadata::getLatterDefinitions(const Variable *Var) const { 371 VariablesMetadata::getLatterDefinitions(const Variable *Var) const {
378 assert(Kind == VMK_All); 372 assert(Kind == VMK_All);
379 if (!isTracked(Var)) 373 if (!isTracked(Var))
380 return NoDefinitions; 374 return NoDefinitions;
381 SizeT VarNum = Var->getIndex(); 375 SizeT VarNum = Var->getIndex();
382 return Metadata[VarNum].getLatterDefinitions(); 376 return Metadata[VarNum].getLatterDefinitions();
383 } 377 }
384 378
385 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { 379 CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const {
386 if (!isTracked(Var)) 380 if (!isTracked(Var))
387 return nullptr; // conservative answer 381 return nullptr; // conservative answer
388 SizeT VarNum = Var->getIndex(); 382 SizeT VarNum = Var->getIndex();
389 return Metadata[VarNum].getNode(); 383 return Metadata[VarNum].getNode();
390 } 384 }
391 385
392 const InstDefList VariablesMetadata::NoDefinitions; 386 const InstDefList VariablesMetadata::NoDefinitions;
393 387
394 // ======================== dump routines ======================== // 388 // ======================== dump routines ======================== //
395 389
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 if (getType() != IceType_i32 && getType() != IceType_i16 && 503 if (getType() != IceType_i32 && getType() != IceType_i16 &&
510 getType() != IceType_i8) 504 getType() != IceType_i8)
511 return false; 505 return false;
512 // The Following checks if the signed representation of Value is between 506 // The Following checks if the signed representation of Value is between
513 // -Threshold/2 and +Threshold/2 507 // -Threshold/2 and +Threshold/2
514 bool largerThanThreshold = Threshold / 2 + Value >= Threshold; 508 bool largerThanThreshold = Threshold / 2 + Value >= Threshold;
515 return largerThanThreshold; 509 return largerThanThreshold;
516 } 510 }
517 511
518 } // end of namespace Ice 512 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698