OLD | NEW |
1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===// | 1 //===- subzero/src/IceCfg.cpp - Control flow graph 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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 TimerMarker T(TimerStack::TT_phiValidation, this); | 250 TimerMarker T(TimerStack::TT_phiValidation, this); |
251 for (CfgNode *Node : Nodes) | 251 for (CfgNode *Node : Nodes) |
252 Node->validatePhis(); | 252 Node->validatePhis(); |
253 } | 253 } |
254 | 254 |
255 void Cfg::renumberInstructions() { | 255 void Cfg::renumberInstructions() { |
256 TimerMarker T(TimerStack::TT_renumberInstructions, this); | 256 TimerMarker T(TimerStack::TT_renumberInstructions, this); |
257 NextInstNumber = Inst::NumberInitial; | 257 NextInstNumber = Inst::NumberInitial; |
258 for (CfgNode *Node : Nodes) | 258 for (CfgNode *Node : Nodes) |
259 Node->renumberInstructions(); | 259 Node->renumberInstructions(); |
| 260 // Make sure the entry node is the first node and therefore got the lowest |
| 261 // instruction numbers, to facilitate live range computation of function |
| 262 // arguments. We want to model function arguments as being live on entry to |
| 263 // the function, otherwise an argument whose only use is in the first |
| 264 // instruction will be assigned a trivial live range and the register |
| 265 // allocator will not recognize its live range as overlapping another |
| 266 // variable's live range. |
| 267 assert(Nodes.empty() || (*Nodes.begin() == getEntryNode())); |
260 } | 268 } |
261 | 269 |
262 // placePhiLoads() must be called before placePhiStores(). | 270 // placePhiLoads() must be called before placePhiStores(). |
263 void Cfg::placePhiLoads() { | 271 void Cfg::placePhiLoads() { |
264 TimerMarker T(TimerStack::TT_placePhiLoads, this); | 272 TimerMarker T(TimerStack::TT_placePhiLoads, this); |
265 for (CfgNode *Node : Nodes) | 273 for (CfgNode *Node : Nodes) |
266 Node->placePhiLoads(); | 274 Node->placePhiLoads(); |
267 } | 275 } |
268 | 276 |
269 // placePhiStores() must be called after placePhiLoads(). | 277 // placePhiStores() must be called after placePhiLoads(). |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 } | 840 } |
833 } | 841 } |
834 if (Mode == Liveness_Intervals) { | 842 if (Mode == Liveness_Intervals) { |
835 // Special treatment for live in-args. Their liveness needs to extend | 843 // Special treatment for live in-args. Their liveness needs to extend |
836 // beyond the beginning of the function, otherwise an arg whose only use | 844 // beyond the beginning of the function, otherwise an arg whose only use |
837 // is in the first instruction will end up having the trivial live range | 845 // is in the first instruction will end up having the trivial live range |
838 // [2,2) and will *not* interfere with other arguments. So if the first | 846 // [2,2) and will *not* interfere with other arguments. So if the first |
839 // instruction of the method is "r=arg1+arg2", both args may be assigned | 847 // instruction of the method is "r=arg1+arg2", both args may be assigned |
840 // the same register. This is accomplished by extending the entry block's | 848 // the same register. This is accomplished by extending the entry block's |
841 // instruction range from [2,n) to [1,n) which will transform the | 849 // instruction range from [2,n) to [1,n) which will transform the |
842 // problematic [2,2) live ranges into [1,2). | 850 // problematic [2,2) live ranges into [1,2). This extension works because |
| 851 // the entry node is guaranteed to have the lowest instruction numbers. |
843 if (Node == getEntryNode()) { | 852 if (Node == getEntryNode()) { |
844 // TODO(stichnot): Make it a strict requirement that the entry node | |
845 // gets the lowest instruction numbers, so that extending the live | |
846 // range for in-args is guaranteed to work. | |
847 FirstInstNum = Inst::NumberExtended; | 853 FirstInstNum = Inst::NumberExtended; |
| 854 // Just in case the entry node somehow contains no instructions... |
| 855 if (LastInstNum == Inst::NumberSentinel) |
| 856 LastInstNum = FirstInstNum; |
848 } | 857 } |
849 Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum); | 858 // If this node somehow contains no instructions, don't bother trying to |
| 859 // add liveness intervals for it, because variables that are live-in and |
| 860 // live-out will have a bogus interval added. |
| 861 if (FirstInstNum != Inst::NumberSentinel) |
| 862 Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum); |
850 } | 863 } |
851 } | 864 } |
852 } | 865 } |
853 | 866 |
854 // Traverse every Variable of every Inst and verify that it appears within the | 867 // Traverse every Variable of every Inst and verify that it appears within the |
855 // Variable's computed live range. | 868 // Variable's computed live range. |
856 bool Cfg::validateLiveness() const { | 869 bool Cfg::validateLiveness() const { |
857 TimerMarker T(TimerStack::TT_validateLiveness, this); | 870 TimerMarker T(TimerStack::TT_validateLiveness, this); |
858 bool Valid = true; | 871 bool Valid = true; |
859 OstreamLocker L(Ctx); | 872 OstreamLocker L(Ctx); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 } | 1108 } |
1096 } | 1109 } |
1097 // Print each basic block | 1110 // Print each basic block |
1098 for (CfgNode *Node : Nodes) | 1111 for (CfgNode *Node : Nodes) |
1099 Node->dump(this); | 1112 Node->dump(this); |
1100 if (isVerbose(IceV_Instructions)) | 1113 if (isVerbose(IceV_Instructions)) |
1101 Str << "}\n"; | 1114 Str << "}\n"; |
1102 } | 1115 } |
1103 | 1116 |
1104 } // end of namespace Ice | 1117 } // end of namespace Ice |
OLD | NEW |