[llvm-branch-commits] [llvm-branch] r168335 - in /llvm/branches/release_32: ./ lib/Target/NVPTX/NVPTXAsmPrinter.cpp lib/Target/NVPTX/NVPTXISelLowering.cpp lib/Target/NVPTX/NVPTXISelLowering.h test/CodeGen/NVPTX/global-ordering.ll test/CodeGen/NVPTX/pr13291-i1-store.ll

Pawel Wodnicki pawel at 32bitmicro.com
Mon Nov 19 14:25:44 PST 2012


Author: pawel
Date: Mon Nov 19 16:25:44 2012
New Revision: 168335

URL: http://llvm.org/viewvc/llvm-project?rev=168335&view=rev
Log:
Merging r167948, r168198: into the 3.2 release branch

r168198

[NVPTX] Order global variables in def-use order before emiting them in the final assembly


r167948

[NVPTX] Implement custom lowering of loads/stores for i1

Loads from i1 become loads from i8 followed by trunc
Stores to i1 become zext to i8 followed by store to i8

Added:
    llvm/branches/release_32/test/CodeGen/NVPTX/global-ordering.ll
      - copied unchanged from r168198, llvm/trunk/test/CodeGen/NVPTX/global-ordering.ll
    llvm/branches/release_32/test/CodeGen/NVPTX/pr13291-i1-store.ll
      - copied unchanged from r167948, llvm/trunk/test/CodeGen/NVPTX/pr13291-i1-store.ll
Modified:
    llvm/branches/release_32/   (props changed)
    llvm/branches/release_32/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
    llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.cpp
    llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.h

Propchange: llvm/branches/release_32/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Nov 19 16:25:44 2012
@@ -1,3 +1,3 @@
 /llvm/branches/Apple/Pertwee:110850,110961
 /llvm/branches/type-system-rewrite:133420-134817
-/llvm/trunk:155241,167719,167731,167743,167750,167784,167811,167817,167855,167942,167966
+/llvm/trunk:155241,167719,167731,167743,167750,167784,167811,167817,167855,167942,167948,167966,168198

Modified: llvm/branches/release_32/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_32/lib/Target/NVPTX/NVPTXAsmPrinter.cpp?rev=168335&r1=168334&r2=168335&view=diff
==============================================================================
--- llvm/branches/release_32/lib/Target/NVPTX/NVPTXAsmPrinter.cpp (original)
+++ llvm/branches/release_32/lib/Target/NVPTX/NVPTXAsmPrinter.cpp Mon Nov 19 16:25:44 2012
@@ -68,7 +68,54 @@
                                         cl::location(llvm::InterleaveSrcInPtx));
 
 
+namespace {
+/// DiscoverDependentGlobals - Return a set of GlobalVariables on which \p V
+/// depends.
+void DiscoverDependentGlobals(Value *V,
+                              DenseSet<GlobalVariable*> &Globals) {
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+    Globals.insert(GV);
+  else {
+    if (User *U = dyn_cast<User>(V)) {
+      for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) {
+        DiscoverDependentGlobals(U->getOperand(i), Globals);
+      }
+    }
+  }
+}
 
+/// VisitGlobalVariableForEmission - Add \p GV to the list of GlobalVariable
+/// instances to be emitted, but only after any dependents have been added
+/// first.
+void VisitGlobalVariableForEmission(GlobalVariable *GV,
+                                    SmallVectorImpl<GlobalVariable*> &Order,
+                                    DenseSet<GlobalVariable*> &Visited,
+                                    DenseSet<GlobalVariable*> &Visiting) {
+  // Have we already visited this one?
+  if (Visited.count(GV)) return;
+
+  // Do we have a circular dependency?
+  if (Visiting.count(GV))
+    report_fatal_error("Circular dependency found in global variable set");
+
+  // Start visiting this global
+  Visiting.insert(GV);
+
+  // Make sure we visit all dependents first
+  DenseSet<GlobalVariable*> Others;
+  for (unsigned i = 0, e = GV->getNumOperands(); i != e; ++i)
+    DiscoverDependentGlobals(GV->getOperand(i), Others);
+  
+  for (DenseSet<GlobalVariable*>::iterator I = Others.begin(),
+       E = Others.end(); I != E; ++I)
+    VisitGlobalVariableForEmission(*I, Order, Visited, Visiting);
+
+  // Now we can visit ourself
+  Order.push_back(GV);
+  Visited.insert(GV);
+  Visiting.erase(GV);
+}
+}
 
 // @TODO: This is a copy from AsmPrinter.cpp.  The function is static, so we
 // cannot just link to the existing version.
@@ -893,10 +940,27 @@
 
   emitDeclarations(M, OS2);
 
-  // Print out module-level global variables here.
+  // As ptxas does not support forward references of globals, we need to first
+  // sort the list of module-level globals in def-use order. We visit each
+  // global variable in order, and ensure that we emit it *after* its dependent
+  // globals. We use a little extra memory maintaining both a set and a list to
+  // have fast searches while maintaining a strict ordering.
+  SmallVector<GlobalVariable*,8> Globals;
+  DenseSet<GlobalVariable*> GVVisited;
+  DenseSet<GlobalVariable*> GVVisiting;
+
+  // Visit each global variable, in order
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
-      I != E; ++I)
-    printModuleLevelGV(I, OS2);
+       I != E; ++I)
+    VisitGlobalVariableForEmission(I, Globals, GVVisited, GVVisiting);
+
+  assert(GVVisited.size() == M.getGlobalList().size() && 
+         "Missed a global variable");
+  assert(GVVisiting.size() == 0 && "Did not fully process a global variable");
+
+  // Print out module-level global variables in proper order
+  for (unsigned i = 0, e = Globals.size(); i != e; ++i)
+    printModuleLevelGV(Globals[i], OS2);
 
   OS2 << '\n';
 

Modified: llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.cpp?rev=168335&r1=168334&r2=168335&view=diff
==============================================================================
--- llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.cpp (original)
+++ llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.cpp Mon Nov 19 16:25:44 2012
@@ -174,10 +174,11 @@
   setTruncStoreAction(MVT::f64, MVT::f32, Expand);
 
   // PTX does not support load / store predicate registers
-  setOperationAction(ISD::LOAD, MVT::i1, Expand);
+  setOperationAction(ISD::LOAD, MVT::i1, Custom);
+  setOperationAction(ISD::STORE, MVT::i1, Custom);
+
   setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
   setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
-  setOperationAction(ISD::STORE, MVT::i1, Expand);
   setTruncStoreAction(MVT::i64, MVT::i1, Expand);
   setTruncStoreAction(MVT::i32, MVT::i1, Expand);
   setTruncStoreAction(MVT::i16, MVT::i1, Expand);
@@ -856,11 +857,66 @@
   case ISD::EXTRACT_SUBVECTOR:
     return Op;
   case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
+  case ISD::STORE: return LowerSTORE(Op, DAG);
+  case ISD::LOAD: return LowerLOAD(Op, DAG);
   default:
     llvm_unreachable("Custom lowering not defined for operation");
   }
 }
 
+
+// v = ld i1* addr
+//   =>
+// v1 = ld i8* addr
+// v = trunc v1 to i1
+SDValue NVPTXTargetLowering::
+LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
+  SDNode *Node = Op.getNode();
+  LoadSDNode *LD = cast<LoadSDNode>(Node);
+  DebugLoc dl = Node->getDebugLoc();
+  ISD::LoadExtType ExtType = LD->getExtensionType();
+  assert(ExtType == ISD::NON_EXTLOAD) ;
+  EVT VT = Node->getValueType(0);
+  assert(VT == MVT::i1 && "Custom lowering for i1 load only");
+  SDValue newLD = DAG.getLoad(MVT::i8, dl, LD->getChain(), LD->getBasePtr(),
+                              LD->getPointerInfo(),
+                              LD->isVolatile(), LD->isNonTemporal(),
+                              LD->isInvariant(),
+                              LD->getAlignment());
+  SDValue result = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, newLD);
+  // The legalizer (the caller) is expecting two values from the legalized
+  // load, so we build a MergeValues node for it. See ExpandUnalignedLoad()
+  // in LegalizeDAG.cpp which also uses MergeValues.
+  SDValue Ops[] = {result, LD->getChain()};
+  return DAG.getMergeValues(Ops, 2, dl);
+}
+
+// st i1 v, addr
+//    =>
+// v1 = zxt v to i8
+// st i8, addr
+SDValue NVPTXTargetLowering::
+LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
+  SDNode *Node = Op.getNode();
+  DebugLoc dl = Node->getDebugLoc();
+  StoreSDNode *ST = cast<StoreSDNode>(Node);
+  SDValue Tmp1 = ST->getChain();
+  SDValue Tmp2 = ST->getBasePtr();
+  SDValue Tmp3 = ST->getValue();
+  EVT VT = Tmp3.getValueType();
+  assert(VT == MVT::i1 && "Custom lowering for i1 store only");
+  unsigned Alignment = ST->getAlignment();
+  bool isVolatile = ST->isVolatile();
+  bool isNonTemporal = ST->isNonTemporal();
+  Tmp3 = DAG.getNode(ISD::ZERO_EXTEND, dl,
+                     MVT::i8, Tmp3);
+  SDValue Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2,
+                                ST->getPointerInfo(), isVolatile,
+                                isNonTemporal, Alignment);
+  return Result;
+}
+
+
 SDValue
 NVPTXTargetLowering::getExtSymb(SelectionDAG &DAG, const char *inname, int idx,
                                 EVT v) const {

Modified: llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.h?rev=168335&r1=168334&r2=168335&view=diff
==============================================================================
--- llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.h (original)
+++ llvm/branches/release_32/lib/Target/NVPTX/NVPTXISelLowering.h Mon Nov 19 16:25:44 2012
@@ -138,6 +138,9 @@
   SDValue getParamHelpSymbol(SelectionDAG &DAG, int idx);
 
   SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
+
+  SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
+  SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
 };
 } // namespace llvm
 





More information about the llvm-branch-commits mailing list