PTX: Use external symbols to keep track of params and locals. This also fixes
a couple of outstanding issues with frame objects occuring as instruction
operands.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140616 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PTX/PTXMachineFunctionInfo.h b/lib/Target/PTX/PTXMachineFunctionInfo.h
index b2d3bb2..f40d8ca 100644
--- a/lib/Target/PTX/PTXMachineFunctionInfo.h
+++ b/lib/Target/PTX/PTXMachineFunctionInfo.h
@@ -38,9 +38,11 @@
   typedef std::vector<unsigned> RegisterList;
   typedef DenseMap<const TargetRegisterClass*, RegisterList> RegisterMap;
   typedef DenseMap<unsigned, std::string> RegisterNameMap;
+  typedef DenseMap<int, std::string> FrameMap;
 
   RegisterMap UsedRegs;
   RegisterNameMap RegNames;
+  FrameMap FrameSymbols;
 
   PTXParamManager ParamManager;
 
@@ -141,6 +143,21 @@
     return UsedRegs.lookup(TRC).size();
   }
 
+  /// getFrameSymbol - Returns the symbol name for the given FrameIndex.
+  const char* getFrameSymbol(int FrameIndex) {
+    if (FrameSymbols.count(FrameIndex)) {
+      return FrameSymbols.lookup(FrameIndex).c_str();
+    } else {
+      std::string Name = "__local";
+      Name += utostr(FrameIndex);
+      // The whole point of caching this name is to ensure the pointer we pass
+      // to any getExternalSymbol() calls will remain valid for the lifetime of
+      // the back-end instance. This is to work around an issue in SelectionDAG
+      // where symbol names are expected to be life-long strings.
+      FrameSymbols[FrameIndex] = Name;
+      return FrameSymbols[FrameIndex].c_str();
+    }
+  }
 }; // class PTXMachineFunctionInfo
 } // namespace llvm