[llvm-commits] [poolalloc] r118932 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DSNode.h lib/DSA/BottomUpClosure.cpp lib/DSA/DSGraph.cpp lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/TopDownClosure.cpp test/dsa/callgraph/test1.ll test/dsa/local/struct2.ll test/dsa/local/union_P21.ll test/dsa/local/union_P2I.ll

Arushi Aggarwal aggarwa4 at illinois.edu
Fri Nov 12 14:17:29 PST 2010


Author: aggarwa4
Date: Fri Nov 12 16:17:29 2010
New Revision: 118932

URL: http://llvm.org/viewvc/llvm-project?rev=118932&view=rev
Log:
1. Correctly handle the intToPtr and PtrToInt cases
where any such two types might overlap in the type
record stored by DSA. The calculation of this 
happens at the end of each DSA Pass now, as no 
other flags use these flags, and it is cheaper to only
walk through the type records once per node.
2. Allow merging of an array node, with a scalar
node, if both are at 0 offset, and the size of the
scalar node is smaller.
3. Testcase changes for the same


Added:
    poolalloc/trunk/test/dsa/callgraph/test1.ll
    poolalloc/trunk/test/dsa/local/union_P21.ll
Modified:
    poolalloc/trunk/include/dsa/DSGraph.h
    poolalloc/trunk/include/dsa/DSNode.h
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/DSGraph.cpp
    poolalloc/trunk/lib/DSA/DataStructure.cpp
    poolalloc/trunk/lib/DSA/Local.cpp
    poolalloc/trunk/lib/DSA/TopDownClosure.cpp
    poolalloc/trunk/test/dsa/local/struct2.ll
    poolalloc/trunk/test/dsa/local/union_P2I.ll

Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Fri Nov 12 16:17:29 2010
@@ -506,6 +506,9 @@
     MarkVAStart = 4
   };
   void markIncompleteNodes(unsigned Flags);
+  
+  // Mark nodes that have overlapping Int and Pointer types.
+  void computeIntPtrFlags();
 
   // Mark all reachable from external as external.
   enum ComputeExternalFlags {

Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Fri Nov 12 16:17:29 2010
@@ -252,6 +252,11 @@
     return true;
   }
 
+  /// markIntPtrFlags - If the node at any offset has overlapping int/ptr types
+  /// mark the P2I flags.
+  ///
+  void markIntPtrFlags();
+
   /// foldNodeCompletely - If we determine that this node has some funny
   /// behavior happening to it that we cannot represent, we fold it down to a
   /// single, completely pessimistic, node.  This node is represented as a

Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Fri Nov 12 16:17:29 2010
@@ -135,6 +135,7 @@
   // Mark external globals incomplete.
   GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
   GlobalsGraph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
+  GlobalsGraph->computeIntPtrFlags();
 
   //
   // Create equivalence classes for aliasing globals so that we only need to
@@ -155,6 +156,7 @@
       Graph->markIncompleteNodes(DSGraph::MarkFormalArgs |
                                    DSGraph::IgnoreGlobals);
       Graph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
+      Graph->computeIntPtrFlags();
     }
   }
 
@@ -835,6 +837,7 @@
   Graph->maskIncompleteMarkers();
   Graph->markIncompleteNodes(DSGraph::MarkFormalArgs);
   Graph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
+  Graph->computeIntPtrFlags();
   
   //
   // Update the callgraph with the new information that we have gleaned.

Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSGraph.cpp Fri Nov 12 16:17:29 2010
@@ -718,6 +718,14 @@
       markExternalNode(&*I, processedNodes);
   }
 }
+// computeIntPtrFlags -- mark all nodes that must get P2 flags due to type overlap
+void DSGraph::computeIntPtrFlags() {
+  DSGraph::node_iterator I = node_begin(),
+                         E = node_end();
+  for ( ; I != E; ++I ) {
+    I->markIntPtrFlags();
+  }
+}
 
 // computeExternalFlags -- mark all reachable from external as external
 void DSGraph::computeExternalFlags(unsigned Flags) {

Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Fri Nov 12 16:17:29 2010
@@ -319,6 +319,78 @@
   return;
 }
 
+/// markIntPtrFlags - Mark P2 flags on node, if integer and pointer types
+/// overlap at any offset.
+///
+void DSNode::markIntPtrFlags() {
+  // check if the types merged have both int and pointer at the same offset,
+  
+  const TargetData &TD = getParentGraph()->getTargetData();
+  // check all offsets for that node.
+  for(unsigned offset = 0; offset < getSize() ; offset++) {
+   // if that Node has no Type information, skip
+   if(TyMap.find(offset) == TyMap.end())
+      continue;
+    
+    bool pointerTy = false;
+    bool integerTy = false;
+    unsigned intSize = 0;
+    unsigned ptrSize = 0;
+
+    // Iterate through all the Types, at that offset, checking if we have
+    // found a pointer type/integer type
+    for (svset<const Type*>::const_iterator ni = TyMap[offset]->begin(),
+         ne = TyMap[offset]->end(); ni != ne; ++ni) {
+      if((*ni)->isPointerTy()) {
+        pointerTy = true;
+        ptrSize = TD.getPointerSize();
+      }
+      if((*ni)->isIntegerTy()) {
+        integerTy = true;
+        if (TD.getTypeStoreSize(*ni) > intSize)
+          intSize = TD.getTypeStoreSize(*ni);
+      }
+    }
+    // If this offset itself contains both pointer and integer, set the
+    // flags and exit.
+    if(pointerTy && integerTy){
+      setUnknownMarker()->setIntToPtrMarker()->setPtrToIntMarker();
+      return;
+    }
+    if(!pointerTy && !integerTy){
+      continue;
+    }
+   
+    // If only either integer or pointer was found, we must see if it 
+    // overlaps with any other pointer or integer type at an offset that
+    // comes later. 
+    unsigned maxOffset = offset + (pointerTy ? ptrSize:intSize);
+    unsigned offset2 = offset;
+    while(offset2 < maxOffset && offset2 < getSize()) {
+      if(TyMap.find(offset2) == TyMap.end()) {
+        offset2++;
+        continue;
+      }
+      for (svset<const Type*>::const_iterator ni = TyMap[offset2]->begin(),
+           ne = TyMap[offset2]->end(); ni != ne; ++ni) {
+        if((*ni)->isPointerTy()) {
+          pointerTy = true;
+        }
+        if((*ni)->isIntegerTy()) {
+          integerTy = true;
+        }
+      }
+      // whenever we have found overlapping integer and pointer types,
+      // we can set the flags, and exit.
+      if(pointerTy && integerTy){
+        setUnknownMarker()->setIntToPtrMarker()->setPtrToIntMarker();
+        return;
+      }
+      offset2++;
+    }
+  }
+}
+
 /// mergeTypeInfo - This method merges the specified type into the current node
 /// at the specified offset.  This may update the current node's type record if
 /// this gives more information to the node, it may do nothing to the node if
@@ -341,31 +413,6 @@
 
   TyMap[Offset] = getParentGraph()->getTypeSS().getOrCreate(TyMap[Offset], NewTy);
 
-  // check if the types merged have both int and pointer at the same offset,
-  // If yes, the IntToPtr and PtrToInt flag must be set on the node pointed to at
-  // that offset. If no such node exists, it is created.
- 
-  bool pointerTy = false;
-  bool integerTy = false;
-  for (svset<const Type*>::const_iterator ni = TyMap[Offset]->begin(),
-       ne = TyMap[Offset]->end(); ni != ne; ++ni) {
-    if((*ni)->isPointerTy()) {
-      pointerTy = true;
-    }
-    if((*ni)->isIntegerTy()) {
-      integerTy = true;
-    }
-  }
-
-  if(pointerTy && integerTy) {
-    if(!hasLink(Offset)) {
-      const DSNodeHandle &NH  = new DSNode(getParentGraph());
-      addEdgeTo(Offset, NH);
-    }
-    DSNodeHandle &Edge = getLink(Offset);
-    assert(!Edge.isNull());
-    Edge.getNode()->setUnknownMarker()->setIntToPtrMarker()->setPtrToIntMarker();
-  }
   assert(TyMap[Offset]);
 }
 
@@ -381,32 +428,6 @@
     TyMap[Offset] = getParentGraph()->getTypeSS().getOrCreate(S);
   }
   
-  // check if the types merged have both int and pointer at the same offset,
-  // If yes, the IntToPtr and PtrToInt flag must be set on the node pointed to at
-  // that offset. If no such node exists, it is created.
-  bool pointerTy = false;
-  bool integerTy = false;
-  for (svset<const Type*>::const_iterator ni = TyMap[Offset]->begin(),
-       ne = TyMap[Offset]->end(); ni != ne; ++ni) {
-    if((*ni)->isPointerTy()) {
-      pointerTy = true;
-    }
-    if((*ni)->isIntegerTy()) {
-      integerTy = true;
-    }
-    const TargetData &TD = getParentGraph()->getTargetData();
-    if ((Offset + TD.getTypeAllocSize(*ni))>= getSize()) growSize(Offset+TD.getTypeAllocSize(*ni));
-  }
-  if(pointerTy && integerTy) {
-    if(!hasLink(Offset)) {
-      const DSNodeHandle &NH  = new DSNode(getParentGraph());
-      addEdgeTo(Offset, NH);
-    }
-    DSNodeHandle &Edge = getLink(Offset);
-    assert(!Edge.isNull());
-    Edge.getNode()->setUnknownMarker()->setIntToPtrMarker()->setPtrToIntMarker();
-  }
-
   assert(TyMap[Offset]);
 }
 
@@ -436,7 +457,6 @@
   }
 }
 
-
 void DSNode::mergeGlobals(const DSNode &RHS) {
   Globals.insert(RHS.Globals.begin(), RHS.Globals.end());
 }
@@ -508,18 +528,33 @@
     NOffset = NH.getOffset();
     assert(NOffset == 0 && NSize == 1);
   }
-
-  if((NH.getNode()->isArrayNode() && !CurNodeH.getNode()->isArrayNode()) ||
-  (!NH.getNode()->isArrayNode() && CurNodeH.getNode()->isArrayNode())) {
-    if(NH.getNode()->getSize() != 0 && CurNodeH.getNode()->getSize() != 0
-       && (NH.getNode()->getSize() != CurNodeH.getNode()->getSize())){
-      CurNodeH.getNode()->foldNodeCompletely();
-      NH.getNode()->foldNodeCompletely();
-      NSize = NH.getNode()->getSize();
-  //    N = NH.getNode();
-      NOffset = NH.getOffset();
+  
+  // FIXME:Add comments.
+  if(NH.getNode()->isArrayNode() && !CurNodeH.getNode()->isArrayNode()) {
+    if(NH.getNode()->getSize() != 0 && CurNodeH.getNode()->getSize() != 0) { 
+      if((NH.getNode()->getSize() != CurNodeH.getNode()->getSize() &&
+       (NH.getOffset() != 0 || CurNodeH.getOffset() != 0) 
+        && NH.getNode()->getSize() < CurNodeH.getNode()->getSize())) {
+        CurNodeH.getNode()->foldNodeCompletely();
+        NH.getNode()->foldNodeCompletely();
+        NSize = NH.getNode()->getSize();
+        NOffset = NH.getOffset();
+      }
     }
   }
+  if(!NH.getNode()->isArrayNode() && CurNodeH.getNode()->isArrayNode()) {
+    if(NH.getNode()->getSize() != 0 && CurNodeH.getNode()->getSize() != 0) { 
+      if((NH.getNode()->getSize() != CurNodeH.getNode()->getSize() &&
+       (NH.getOffset() != 0 || CurNodeH.getOffset() != 0) 
+        && NH.getNode()->getSize() > CurNodeH.getNode()->getSize())) {
+        CurNodeH.getNode()->foldNodeCompletely();
+        NH.getNode()->foldNodeCompletely();
+        NSize = NH.getNode()->getSize();
+        NOffset = NH.getOffset();
+      }
+    }
+  }
+
   if (CurNodeH.getNode()->isArrayNode() && NH.getNode()->isArrayNode()) {
     if(NH.getNode()->getSize() != 0 && CurNodeH.getNode()->getSize() != 0
        && (NH.getNode()->getSize() != CurNodeH.getNode()->getSize())){
@@ -542,8 +577,6 @@
     CurNodeH.getNode()->growSize(NH.getNode()->getSize() + NOffset);
   assert(!CurNodeH.getNode()->isDeadNode());
 
-
-
   // Merge the NodeType information.
   CurNodeH.getNode()->NodeType |= N->NodeType;
 
@@ -785,29 +818,45 @@
           DN = NH.getNode();
         }
 #endif
-     }
+      }
+      
+     
+      // FIXME:Add comments.
+      if(!DN->isArrayNode() && SN->isArrayNode()) {
+        if(DN->getSize() != 0 && SN->getSize() != 0) { 
+          if((DN->getSize() != SN->getSize() &&
+            (NH.getOffset() != 0 || SrcNH.getOffset() != 0) 
+            && DN->getSize() > SN->getSize())) {
+            DN->foldNodeCompletely();
+            DN = NH.getNode();
+          }
+        }
+      }
+      if(!SN->isArrayNode() && DN->isArrayNode()) {
+        if(DN->getSize() != 0 && SN->getSize() != 0) { 
+          if((DN->getSize() != SN->getSize() &&
+            (NH.getOffset() != 0 || SrcNH.getOffset() != 0) 
+            && DN->getSize() < SN->getSize())) {
+            DN->foldNodeCompletely();
+            DN = NH.getNode();
+          }
+        }
+      } 
 
-     if ((SN->isArrayNode() && !DN->isArrayNode()) ||
-        (!SN->isArrayNode() && DN->isArrayNode())) {
-        if(SN->getSize() != 0 && DN->getSize() != 0
-         && (SN->getSize() != DN->getSize())){
-          DN->foldNodeCompletely();
-          DN = NH.getNode();
+      if (SN->isArrayNode() && DN->isArrayNode()) {
+        if((SN->getSize() != DN->getSize()) && (SN->getSize() != 0) 
+           && DN->getSize() != 0) {
+           DN->foldNodeCompletely();
+           DN = NH.getNode();
         }
-     }
-     if (SN->isArrayNode() && DN->isArrayNode()) {
-        if((SN->getSize() != DN->getSize()) && (SN->getSize() != 0) && DN->getSize() != 0) {
-        DN->foldNodeCompletely();
-        DN = NH.getNode();
-       }
-    }
-    if (!DN->isNodeCompletelyFolded() && DN->getSize() < SN->getSize())
-      DN->growSize(SN->getSize());
+      }
+      if (!DN->isNodeCompletelyFolded() && DN->getSize() < SN->getSize())
+        DN->growSize(SN->getSize());
 
 
       // Merge the type entries of the two nodes together...
       if (!DN->isNodeCompletelyFolded())
-          DN->mergeTypeInfo(SN, NH.getOffset() - SrcNH.getOffset());
+        DN->mergeTypeInfo(SN, NH.getOffset() - SrcNH.getOffset());
     }
 
     assert(!DN->isDeadNode());

Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Fri Nov 12 16:17:29 2010
@@ -188,6 +188,7 @@
         | DSGraph::ProcessCallSites;
 
       g.computeExternalFlags(EFlags);
+      g.computeIntPtrFlags();
 
       // Remove any nodes made dead due to merging...
       g.removeDeadNodes(DSGraph::KeepUnreachableGlobals);

Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Fri Nov 12 16:17:29 2010
@@ -165,6 +165,7 @@
   ExternallyCallable.clear();
   GlobalsGraph->removeTriviallyDeadNodes();
   GlobalsGraph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
+  GlobalsGraph->computeIntPtrFlags();
 
   // Make sure each graph has updated external information about globals
   // in the globals graph.
@@ -184,6 +185,7 @@
       Graph->removeDeadNodes(0);
 
       Graph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
+      Graph->computeIntPtrFlags();
 
     }
   }
@@ -311,6 +313,7 @@
   unsigned ExtFlags
     = isExternallyCallable ? DSGraph::MarkFormalsExternal : DSGraph::DontMarkFormalsExternal;
   DSG->computeExternalFlags(ExtFlags);
+  DSG->computeIntPtrFlags();
 
   {
     DSGraph* GG = DSG->getGlobalsGraph();

Added: poolalloc/trunk/test/dsa/callgraph/test1.ll
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/callgraph/test1.ll?rev=118932&view=auto
==============================================================================
--- poolalloc/trunk/test/dsa/callgraph/test1.ll (added)
+++ poolalloc/trunk/test/dsa/callgraph/test1.ll Fri Nov 12 16:17:29 2010
@@ -0,0 +1,110 @@
+;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=lreadf,f_ungetc,lreadr
+;RUN: dsaopt %s -dsa-cbu -analyze -check-callees=lreadr,f_ungetc,f_getc
+
+; ModuleID = 'test1.o'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct.FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct.FILE*, i32 }
+%struct.gen_readio = type { i32 (i8*)*, void (i32, i8*)*, i8* }
+
+define i32* @lreadr(%struct.gen_readio* %f) nounwind {
+entry:
+  %f_addr = alloca %struct.gen_readio*            ; <%struct.gen_readio**> [#uses=5]
+  %retval = alloca i32*                           ; <i32**> [#uses=2]
+  %0 = alloca i32*                                ; <i32**> [#uses=2]
+  %t = alloca i32                                 ; <i32*> [#uses=2]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store %struct.gen_readio* %f, %struct.gen_readio** %f_addr
+  %1 = load %struct.gen_readio** %f_addr, align 8 ; <%struct.gen_readio*> [#uses=1]
+  %2 = getelementptr inbounds %struct.gen_readio* %1, i32 0, i32 0 ; <i32 (i8*)**> [#uses=1]
+  %3 = load i32 (i8*)** %2, align 8               ; <i32 (i8*)*> [#uses=1]
+  %4 = load %struct.gen_readio** %f_addr, align 8 ; <%struct.gen_readio*> [#uses=1]
+  %5 = getelementptr inbounds %struct.gen_readio* %4, i32 0, i32 2 ; <i8**> [#uses=1]
+  %6 = load i8** %5, align 8                      ; <i8*> [#uses=1]
+  %7 = call i32 %3(i8* %6) nounwind               ; <i32> [#uses=1]
+  store i32 %7, i32* %t, align 4
+  %8 = load %struct.gen_readio** %f_addr, align 8 ; <%struct.gen_readio*> [#uses=1]
+  %9 = getelementptr inbounds %struct.gen_readio* %8, i32 0, i32 1 ; <void (i32, i8*)**> [#uses=1]
+  %10 = load void (i32, i8*)** %9, align 8        ; <void (i32, i8*)*> [#uses=1]
+  %11 = load %struct.gen_readio** %f_addr, align 8 ; <%struct.gen_readio*> [#uses=1]
+  %12 = getelementptr inbounds %struct.gen_readio* %11, i32 0, i32 2 ; <i8**> [#uses=1]
+  %13 = load i8** %12, align 8                    ; <i8*> [#uses=1]
+  %14 = load i32* %t, align 4                     ; <i32> [#uses=1]
+  call void %10(i32 %14, i8* %13) nounwind
+  %15 = call noalias i8* @malloc(i64 4) nounwind  ; <i8*> [#uses=1]
+  %16 = bitcast i8* %15 to i32*                   ; <i32*> [#uses=1]
+  store i32* %16, i32** %0, align 8
+  %17 = load i32** %0, align 8                    ; <i32*> [#uses=1]
+  store i32* %17, i32** %retval, align 8
+  br label %return
+
+return:                                           ; preds = %entry
+  %retval1 = load i32** %retval                   ; <i32*> [#uses=1]
+  ret i32* %retval1
+}
+
+declare noalias i8* @malloc(i64) nounwind
+
+define void @init(%struct.gen_readio* %f, i32 (i8*)* %fcn) nounwind {
+entry:
+  %f_addr = alloca %struct.gen_readio*            ; <%struct.gen_readio**> [#uses=2]
+  %fcn_addr = alloca i32 (i8*)*                   ; <i32 (i8*)**> [#uses=2]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store %struct.gen_readio* %f, %struct.gen_readio** %f_addr
+  store i32 (i8*)* %fcn, i32 (i8*)** %fcn_addr
+  %0 = load %struct.gen_readio** %f_addr, align 8 ; <%struct.gen_readio*> [#uses=1]
+  %1 = getelementptr inbounds %struct.gen_readio* %0, i32 0, i32 0 ; <i32 (i8*)**> [#uses=1]
+  %2 = load i32 (i8*)** %fcn_addr, align 8        ; <i32 (i8*)*> [#uses=1]
+  store i32 (i8*)* %2, i32 (i8*)** %1, align 8
+  br label %return
+
+return:                                           ; preds = %entry
+  ret void
+}
+
+define i32* @lreadf(%struct.FILE* %f) nounwind {
+entry:
+  %f_addr = alloca %struct.FILE*                  ; <%struct.FILE**> [#uses=2]
+  %retval = alloca i32*                           ; <i32**> [#uses=2]
+  %0 = alloca i32*                                ; <i32**> [#uses=2]
+  %s = alloca %struct.gen_readio                  ; <%struct.gen_readio*> [#uses=6]
+  %c = alloca i32                                 ; <i32*> [#uses=1]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store %struct.FILE* %f, %struct.FILE** %f_addr
+  call void @init(%struct.gen_readio* %s, i32 (i8*)* bitcast (i32 (%struct.FILE*)* @f_getc to i32 (i8*)*)) nounwind
+  %1 = getelementptr inbounds %struct.gen_readio* %s, i32 0, i32 1 ; <void (i32, i8*)**> [#uses=1]
+  store void (i32, i8*)* bitcast (void (i32, %struct.FILE*)* @f_ungetc to void (i32, i8*)*), void (i32, i8*)** %1, align 8
+  %2 = getelementptr inbounds %struct.gen_readio* %s, i32 0, i32 2 ; <i8**> [#uses=1]
+  %3 = load %struct.FILE** %f_addr, align 8       ; <%struct.FILE*> [#uses=1]
+  %4 = bitcast %struct.FILE* %3 to i8*            ; <i8*> [#uses=1]
+  store i8* %4, i8** %2, align 8
+  %5 = getelementptr inbounds %struct.gen_readio* %s, i32 0, i32 1 ; <void (i32, i8*)**> [#uses=1]
+  %6 = load void (i32, i8*)** %5, align 8         ; <void (i32, i8*)*> [#uses=1]
+  %7 = getelementptr inbounds %struct.gen_readio* %s, i32 0, i32 2 ; <i8**> [#uses=1]
+  %8 = load i8** %7, align 8                      ; <i8*> [#uses=1]
+  %9 = load i32* %c, align 4                      ; <i32> [#uses=1]
+  call void %6(i32 %9, i8* %8) nounwind
+  %10 = call i32* @lreadr(%struct.gen_readio* %s) nounwind ; <i32*> [#uses=1]
+  store i32* %10, i32** %0, align 8
+  %11 = load i32** %0, align 8                    ; <i32*> [#uses=1]
+  store i32* %11, i32** %retval, align 8
+  br label %return
+
+return:                                           ; preds = %entry
+  %retval1 = load i32** %retval                   ; <i32*> [#uses=1]
+  ret i32* %retval1
+}
+
+declare i32 @f_getc(%struct.FILE*)
+
+declare void @f_ungetc(i32, %struct.FILE*)
+
+define void @main() nounwind {
+entry:
+  br label %return
+
+return:                                           ; preds = %entry
+  ret void
+}

Modified: poolalloc/trunk/test/dsa/local/struct2.ll
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/local/struct2.ll?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/test/dsa/local/struct2.ll (original)
+++ poolalloc/trunk/test/dsa/local/struct2.ll Fri Nov 12 16:17:29 2010
@@ -2,8 +2,8 @@
 
 ;RUN: dsaopt %s -dsa-local -analyze -check-type=main:r,0:i64|i32*::8:i32*
 ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=main:r:0,main:x
-;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:x+SUP2-MR"
-;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:y+S-UP2MR"
+;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:r+SUP2"
+;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:r1+SUP2"
 
 ; ModuleID = 'struct2.bc'
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

Added: poolalloc/trunk/test/dsa/local/union_P21.ll
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/local/union_P21.ll?rev=118932&view=auto
==============================================================================
--- poolalloc/trunk/test/dsa/local/union_P21.ll (added)
+++ poolalloc/trunk/test/dsa/local/union_P21.ll Fri Nov 12 16:17:29 2010
@@ -0,0 +1,49 @@
+;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:obj1+UP2"
+;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:obj+UP2"
+;RUN: dsaopt %s -dsa-local -analyze -check-type=main:obj,0:i32*::4:i32
+;RUN: dsaopt %s -dsa-local -analyze -check-type=main:obj1,0:i32|i32*
+
+; if any part of pointer overlaps with an interger, we must mark the into to ptr flag.
+ 
+
+; ModuleID = 'union_P21.o'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.StructType = type { i32, i32 }
+%union.UnionType = type { i32* }
+
+define i32 @main() nounwind {
+entry:
+  %retval = alloca i32                            ; <i32*> [#uses=1]
+  %obj = alloca %union.UnionType                  ; <%union.UnionType*> [#uses=2]
+  %d = alloca i32                                 ; <i32*> [#uses=1]
+  %obj1 = alloca %union.UnionType                 ; <%union.UnionType*> [#uses=2]
+  %e = alloca i32                                 ; <i32*> [#uses=1]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  %0 = call noalias i8* @malloc(i64 4) nounwind   ; <i8*> [#uses=1]
+  %1 = bitcast i8* %0 to i32*                     ; <i32*> [#uses=1]
+  %2 = getelementptr inbounds %union.UnionType* %obj, i32 0, i32 0 ; <i32**> [#uses=1]
+  store i32* %1, i32** %2, align 8
+  %3 = getelementptr inbounds %union.UnionType* %obj, i32 0, i32 0 ; <i32**> [#uses=1]
+  %4 = bitcast i32** %3 to %struct.StructType*    ; <%struct.StructType*> [#uses=1]
+  %5 = getelementptr inbounds %struct.StructType* %4, i32 0, i32 1 ; <i32*> [#uses=1]
+  %6 = load i32* %5, align 4                      ; <i32> [#uses=1]
+  store i32 %6, i32* %d, align 4
+  %7 = call noalias i8* @malloc(i64 4) nounwind   ; <i8*> [#uses=1]
+  %8 = bitcast i8* %7 to i32*                     ; <i32*> [#uses=1]
+  %9 = getelementptr inbounds %union.UnionType* %obj1, i32 0, i32 0 ; <i32**> [#uses=1]
+  store i32* %8, i32** %9, align 8
+  %10 = getelementptr inbounds %union.UnionType* %obj1, i32 0, i32 0 ; <i32**> [#uses=1]
+  %11 = bitcast i32** %10 to %struct.StructType*  ; <%struct.StructType*> [#uses=1]
+  %12 = getelementptr inbounds %struct.StructType* %11, i32 0, i32 0 ; <i32*> [#uses=1]
+  %13 = load i32* %12, align 8                    ; <i32> [#uses=1]
+  store i32 %13, i32* %e, align 4
+  br label %return
+
+return:                                           ; preds = %entry
+  %retval1 = load i32* %retval                    ; <i32> [#uses=1]
+  ret i32 %retval1
+}
+
+declare noalias i8* @malloc(i64) nounwind

Modified: poolalloc/trunk/test/dsa/local/union_P2I.ll
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/local/union_P2I.ll?rev=118932&r1=118931&r2=118932&view=diff
==============================================================================
--- poolalloc/trunk/test/dsa/local/union_P2I.ll (original)
+++ poolalloc/trunk/test/dsa/local/union_P2I.ll Fri Nov 12 16:17:29 2010
@@ -1,7 +1,7 @@
 ;checks that the PtrToInt and IntToPtr flag is set on unions that contain integer and pointer types
 
 ;RUN: dsaopt %s -dsa-local -analyze -check-same-node=main:ptr:0,main:obj:0
-;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:ptr:0+UP2"
+;RUN: dsaopt %s -dsa-local -analyze -verify-flags "main:obj+UP2"
 ;RUN: dsaopt %s -dsa-local -analyze -check-type=main:obj,0:i32|%\struct.StructType*
 
 





More information about the llvm-commits mailing list