Chromium Code Reviews| 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 // This file implements the Operand class and its target-independent | 10 // This file implements the Operand class and its target-independent |
| 11 // subclasses, primarily for the methods of the Variable class. | 11 // subclasses, primarily for the methods of the Variable class. |
| 12 // | 12 // |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #include "IceCfg.h" | 15 #include "IceCfg.h" |
| 16 #include "IceCfgNode.h" | |
| 16 #include "IceInst.h" | 17 #include "IceInst.h" |
| 17 #include "IceOperand.h" | 18 #include "IceOperand.h" |
| 18 #include "IceTargetLowering.h" // dumping stack/frame pointer register | 19 #include "IceTargetLowering.h" // dumping stack/frame pointer register |
| 19 | 20 |
| 20 namespace Ice { | 21 namespace Ice { |
| 21 | 22 |
| 22 bool operator<(const RelocatableTuple &A, const RelocatableTuple &B) { | 23 bool operator<(const RelocatableTuple &A, const RelocatableTuple &B) { |
| 23 if (A.Offset != B.Offset) | 24 if (A.Offset != B.Offset) |
| 24 return A.Offset < B.Offset; | 25 return A.Offset < B.Offset; |
| 25 if (A.SuppressMangling != B.SuppressMangling) | 26 if (A.SuppressMangling != B.SuppressMangling) |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 // calculation. | 132 // calculation. |
| 132 bool LiveRange::containsValue(InstNumberT Value) const { | 133 bool LiveRange::containsValue(InstNumberT Value) const { |
| 133 for (RangeType::const_iterator I = Range.begin(), E = Range.end(); I != E; | 134 for (RangeType::const_iterator I = Range.begin(), E = Range.end(); I != E; |
| 134 ++I) { | 135 ++I) { |
| 135 if (I->first <= Value && Value <= I->second) | 136 if (I->first <= Value && Value <= I->second) |
| 136 return true; | 137 return true; |
| 137 } | 138 } |
| 138 return false; | 139 return false; |
| 139 } | 140 } |
| 140 | 141 |
| 141 void Variable::setUse(const Inst *Inst, const CfgNode *Node) { | |
| 142 if (DefNode == NULL) | |
| 143 return; | |
| 144 if (llvm::isa<InstPhi>(Inst) || Node != DefNode) | |
| 145 DefNode = NULL; | |
| 146 } | |
| 147 | |
| 148 void Variable::setDefinition(Inst *Inst, const CfgNode *Node) { | |
| 149 if (DefInst && !DefInst->isDeleted() && DefInst != Inst) { | |
| 150 // Detect when a variable is being defined multiple times, | |
| 151 // particularly for Phi instruction lowering. If this happens, we | |
| 152 // need to lock DefInst to NULL. | |
| 153 DefInst = NULL; | |
| 154 DefNode = NULL; | |
| 155 return; | |
| 156 } | |
| 157 if (DefNode == NULL) | |
| 158 return; | |
| 159 DefInst = Inst; | |
| 160 if (Node != DefNode) | |
| 161 DefNode = NULL; | |
| 162 } | |
| 163 | |
| 164 void Variable::replaceDefinition(Inst *Inst, const CfgNode *Node) { | |
| 165 DefInst = NULL; | |
| 166 setDefinition(Inst, Node); | |
| 167 } | |
| 168 | |
| 169 void Variable::setIsArg(Cfg *Func, bool IsArg) { | |
| 170 if (IsArg) { | |
| 171 IsArgument = true; | |
| 172 if (DefNode == NULL) | |
| 173 return; | |
| 174 CfgNode *Entry = Func->getEntryNode(); | |
| 175 if (DefNode == Entry) | |
| 176 return; | |
| 177 DefNode = NULL; | |
| 178 } else { | |
| 179 IsArgument = false; | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 IceString Variable::getName() const { | 142 IceString Variable::getName() const { |
| 184 if (!Name.empty()) | 143 if (!Name.empty()) |
| 185 return Name; | 144 return Name; |
| 186 char buf[30]; | 145 char buf[30]; |
| 187 snprintf(buf, llvm::array_lengthof(buf), "__%u", getIndex()); | 146 snprintf(buf, llvm::array_lengthof(buf), "__%u", getIndex()); |
| 188 return buf; | 147 return buf; |
| 189 } | 148 } |
| 190 | 149 |
| 191 Variable Variable::asType(Type Ty) { | 150 Variable Variable::asType(Type Ty) { |
| 192 // Note: This returns a Variable, even if the "this" object is a | 151 // Note: This returns a Variable, even if the "this" object is a |
| 193 // subclass of Variable. | 152 // subclass of Variable. |
| 194 Variable V(kVariable, Ty, DefNode, Number, Name); | 153 Variable V(kVariable, Ty, Number, Name); |
| 195 V.RegNum = RegNum; | 154 V.RegNum = RegNum; |
| 196 V.StackOffset = StackOffset; | 155 V.StackOffset = StackOffset; |
| 197 return V; | 156 return V; |
| 198 } | 157 } |
| 199 | 158 |
| 159 void VariablesMetadata::init() { | |
| 160 Metadata.clear(); | |
| 161 Metadata.resize(Func->getNumVariables()); | |
| 162 // Mark args as being used in the entry node. | |
| 163 const CfgNode *Entry = Func->getEntryNode(); | |
| 164 Entry = NULL; | |
| 165 for (SizeT i = 0; i < Func->getNumVariables(); ++i) { | |
| 166 const Variable *Var = Func->getVariables()[i]; | |
| 167 if (Var->getIsArg()) { | |
|
jvoung (off chromium)
2014/09/22 17:07:29
Why not use the Func->getArgs() list, which will h
Jim Stichnoth
2014/09/22 21:00:46
The only problem with using Func->getArgs() is the
| |
| 168 const Inst *NoInst = NULL; | |
| 169 const bool IsFromDef = false; | |
| 170 Metadata[Var->getIndex()].markUse(NoInst, Entry, IsFromDef); | |
| 171 } | |
| 172 } | |
| 173 SizeT NumNodes = Func->getNumNodes(); | |
| 174 for (SizeT N = 0; N < NumNodes; ++N) { | |
| 175 CfgNode *Node = Func->getNodes()[N]; | |
| 176 const InstList &Insts = Node->getInsts(); | |
| 177 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; | |
| 178 ++I) { | |
| 179 if ((*I)->isDeleted()) | |
| 180 continue; | |
| 181 if (Variable *Dest = (*I)->getDest()) { | |
| 182 SizeT DestNum = Dest->getIndex(); | |
| 183 assert(DestNum < Metadata.size()); | |
| 184 Metadata[DestNum].markDef(*I, Node); | |
| 185 } | |
| 186 for (SizeT SrcNum = 0; SrcNum < (*I)->getSrcSize(); ++SrcNum) { | |
| 187 Operand *Src = (*I)->getSrc(SrcNum); | |
| 188 SizeT NumVars = Src->getNumVars(); | |
| 189 for (SizeT J = 0; J < NumVars; ++J) { | |
| 190 const Variable *Var = Src->getVar(J); | |
| 191 SizeT VarNum = Var->getIndex(); | |
| 192 assert(VarNum < Metadata.size()); | |
| 193 const bool IsFromDef = false; | |
| 194 Metadata[VarNum].markUse(*I, Node, IsFromDef); | |
| 195 } | |
| 196 } | |
| 197 } | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 bool VariablesMetadata::isMultiDef(const Variable *Var) const { | |
| 202 if (Var->getIsArg()) | |
| 203 return false; | |
| 204 if (!isTracked(Var)) | |
| 205 return true; // conservative answer | |
| 206 SizeT VarNum = Var->getIndex(); | |
| 207 // Conservatively return true if the state is unknown. | |
| 208 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef; | |
| 209 } | |
| 210 | |
| 211 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { | |
| 212 if (getDefinition(Var) == NULL) | |
| 213 return true; | |
| 214 SizeT VarNum = Var->getIndex(); | |
| 215 // Conservatively return true if the state is unknown. | |
| 216 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; | |
| 217 } | |
| 218 | |
| 219 const Inst *VariablesMetadata::getDefinition(const Variable *Var) const { | |
| 220 if (!isTracked(Var)) | |
| 221 return NULL; // conservative answer | |
| 222 SizeT VarNum = Var->getIndex(); | |
| 223 return Metadata[VarNum].getDefinition(); | |
| 224 } | |
| 225 | |
| 226 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { | |
| 227 if (!isTracked(Var)) | |
| 228 return NULL; // conservative answer | |
| 229 SizeT VarNum = Var->getIndex(); | |
| 230 return Metadata[VarNum].getNode(); | |
| 231 } | |
| 232 | |
| 200 // ======================== dump routines ======================== // | 233 // ======================== dump routines ======================== // |
| 201 | 234 |
| 202 void Variable::emit(const Cfg *Func) const { | 235 void Variable::emit(const Cfg *Func) const { |
| 203 Func->getTarget()->emitVariable(this, Func); | 236 Func->getTarget()->emitVariable(this); |
| 204 } | 237 } |
| 205 | 238 |
| 206 void Variable::dump(const Cfg *Func, Ostream &Str) const { | 239 void Variable::dump(const Cfg *Func, Ostream &Str) const { |
| 207 if (Func == NULL) { | 240 if (Func == NULL) { |
| 208 Str << "%" << getName(); | 241 Str << "%" << getName(); |
| 209 return; | 242 return; |
| 210 } | 243 } |
| 211 const CfgNode *CurrentNode = Func->getCurrentNode(); | |
| 212 (void)CurrentNode; // used only in assert() | |
| 213 assert(CurrentNode == NULL || DefNode == NULL || DefNode == CurrentNode); | |
| 214 if (Func->getContext()->isVerbose(IceV_RegOrigins) || | 244 if (Func->getContext()->isVerbose(IceV_RegOrigins) || |
| 215 (!hasReg() && !Func->getTarget()->hasComputedFrame())) | 245 (!hasReg() && !Func->getTarget()->hasComputedFrame())) |
| 216 Str << "%" << getName(); | 246 Str << "%" << getName(); |
| 217 if (hasReg()) { | 247 if (hasReg()) { |
| 218 if (Func->getContext()->isVerbose(IceV_RegOrigins)) | 248 if (Func->getContext()->isVerbose(IceV_RegOrigins)) |
| 219 Str << ":"; | 249 Str << ":"; |
| 220 Str << Func->getTarget()->getRegName(RegNum, getType()); | 250 Str << Func->getTarget()->getRegName(RegNum, getType()); |
| 221 } else if (Func->getTarget()->hasComputedFrame()) { | 251 } else if (Func->getTarget()->hasComputedFrame()) { |
| 222 if (Func->getContext()->isVerbose(IceV_RegOrigins)) | 252 if (Func->getContext()->isVerbose(IceV_RegOrigins)) |
| 223 Str << ":"; | 253 Str << ":"; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 | 299 |
| 270 Ostream &operator<<(Ostream &Str, const RegWeight &W) { | 300 Ostream &operator<<(Ostream &Str, const RegWeight &W) { |
| 271 if (W.getWeight() == RegWeight::Inf) | 301 if (W.getWeight() == RegWeight::Inf) |
| 272 Str << "Inf"; | 302 Str << "Inf"; |
| 273 else | 303 else |
| 274 Str << W.getWeight(); | 304 Str << W.getWeight(); |
| 275 return Str; | 305 return Str; |
| 276 } | 306 } |
| 277 | 307 |
| 278 } // end of namespace Ice | 308 } // end of namespace Ice |
| OLD | NEW |