| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |