Subzero: Change the way bitcast stack slot lowering is handled. When doing a bitcast between int and FP types, the way lowering works is that a spill temporary is created, with regalloc weight of zero to inhibit register allocation, and this spill temporary is used for the cvt instruction. If the other variable does not get register-allocated, then addProlog() forces the spill temporary to share the same stack slot as the other variable. Currently, the lowering code passes this information to addProlog() by using the setPreferredRegister() mechanism. This is changed by creating a target-specific subclass of Variable, so that only the spill temporaries need to carry this extra information. Ultimately, many of the existing Variable fields will be refactored into a separate structure, and only generated/used as needed by various optimization passes. The spill temporary linkage is the one thing that is still needed with Om1 when no optimizations are enabled, motivating this change. A couple other minor cleanups are also done here. The key test is that the cast cross tests continue to work, specifically the bitcast tests. BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/586943003
diff --git a/src/IceCfg.h b/src/IceCfg.h index a2582eb..7a265ad 100644 --- a/src/IceCfg.h +++ b/src/IceCfg.h
@@ -61,6 +61,17 @@ InstNumberT newInstNumber() { return NextInstNumber++; } // Manage Variables. + // Create a new Variable with a particular type and an optional + // name. The Node argument is the node where the variable is defined. + template <typename T> + T *makeVariable(Type Ty, const CfgNode *Node, const IceString &Name = "") { + SizeT Index = Variables.size(); + T *Var = T::create(this, Ty, Node, Index, Name); + Variables.push_back(Var); + return Var; + } + // TODO(stichnot): Remove this function with C++11, and use default + // argument <typename T=Variable> above. Variable *makeVariable(Type Ty, const CfgNode *Node, const IceString &Name = ""); SizeT getNumVariables() const { return Variables.size(); } @@ -99,6 +110,7 @@ // Manage the CurrentNode field, which is used for validating the // Variable::DefNode field during dumping/emitting. void setCurrentNode(const CfgNode *Node) { CurrentNode = Node; } + void resetCurrentNode() { setCurrentNode(NULL); } const CfgNode *getCurrentNode() const { return CurrentNode; } void emit(); @@ -155,8 +167,8 @@ // CurrentNode is maintained during dumping/emitting just for // validating Variable::DefNode. Normally, a traversal over // CfgNodes maintains this, but before global operations like - // register allocation, setCurrentNode(NULL) should be called to - // avoid spurious validation failures. + // register allocation, resetCurrentNode() should be called to avoid + // spurious validation failures. const CfgNode *CurrentNode; Cfg(const Cfg &) LLVM_DELETED_FUNCTION;