svn commit: r198130 - in projects/clangbsd/contrib/llvm: . include/llvm include/llvm/ADT include/llvm/CodeGen include/llvm/CompilerDriver include/llvm/ExecutionEngine include/llvm/Support lib/Analy...

Roman Divacky rdivacky at FreeBSD.org
Thu Oct 15 13:29:28 UTC 2009


Author: rdivacky
Date: Thu Oct 15 13:29:27 2009
New Revision: 198130
URL: http://svn.freebsd.org/changeset/base/198130

Log:
  Merge llvm r84176 from vendor.

Modified:
  projects/clangbsd/contrib/llvm/   (props changed)
  projects/clangbsd/contrib/llvm/include/llvm/ADT/DenseMapInfo.h
  projects/clangbsd/contrib/llvm/include/llvm/ADT/ImmutableSet.h
  projects/clangbsd/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h
  projects/clangbsd/contrib/llvm/include/llvm/CompilerDriver/CompilationGraph.h
  projects/clangbsd/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h
  projects/clangbsd/contrib/llvm/include/llvm/Metadata.h
  projects/clangbsd/contrib/llvm/include/llvm/Operator.h
  projects/clangbsd/contrib/llvm/include/llvm/Pass.h
  projects/clangbsd/contrib/llvm/include/llvm/Support/CommandLine.h
  projects/clangbsd/contrib/llvm/include/llvm/Support/DebugLoc.h
  projects/clangbsd/contrib/llvm/include/llvm/Support/raw_ostream.h
  projects/clangbsd/contrib/llvm/lib/Analysis/BasicAliasAnalysis.cpp
  projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
  projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
  projects/clangbsd/contrib/llvm/lib/CodeGen/CodePlacementOpt.cpp
  projects/clangbsd/contrib/llvm/lib/CodeGen/LiveVariables.cpp
  projects/clangbsd/contrib/llvm/lib/CodeGen/MachineInstr.cpp
  projects/clangbsd/contrib/llvm/lib/CodeGen/PrologEpilogInserter.cpp
  projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
  projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
  projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMInstrInfo.td
  projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMInstrNEON.td
  projects/clangbsd/contrib/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
  projects/clangbsd/contrib/llvm/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll
  projects/clangbsd/contrib/llvm/test/CodeGen/X86/avoid-loop-align-2.ll
  projects/clangbsd/contrib/llvm/test/CodeGen/X86/avoid-loop-align.ll
  projects/clangbsd/contrib/llvm/tools/clang/   (props changed)
  projects/clangbsd/contrib/llvm/tools/opt/opt.cpp
  projects/clangbsd/contrib/llvm/unittests/ExecutionEngine/JIT/JITTest.cpp

Modified: projects/clangbsd/contrib/llvm/include/llvm/ADT/DenseMapInfo.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/ADT/DenseMapInfo.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/ADT/DenseMapInfo.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -89,7 +89,7 @@ template<> struct DenseMapInfo<unsigned 
   static inline unsigned long long getEmptyKey() { return ~0ULL; }
   static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
   static unsigned getHashValue(const unsigned long long& Val) {
-    return Val * 37ULL;
+    return (unsigned)Val * 37ULL;
   }
   static bool isPod() { return true; }
   static bool isEqual(const unsigned long long& LHS,

Modified: projects/clangbsd/contrib/llvm/include/llvm/ADT/ImmutableSet.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/ADT/ImmutableSet.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/ADT/ImmutableSet.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -988,8 +988,8 @@ public:
     BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
 
   private:
-    Factory(const Factory& RHS) {};
-    void operator=(const Factory& RHS) {};
+    Factory(const Factory& RHS) {}
+    void operator=(const Factory& RHS) {}
   };
 
   friend class Factory;

Modified: projects/clangbsd/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -500,8 +500,8 @@ namespace llvm {
     /// ComputeOperandLatency - Override dependence edge latency using
     /// operand use/def information
     ///
-    virtual void ComputeOperandLatency(SUnit *Def, SUnit *Use,
-                                       SDep& dep) const { };
+    virtual void ComputeOperandLatency(SUnit *, SUnit *,
+                                       SDep&) const { }
 
     /// Schedule - Order nodes according to selected style, filling
     /// in the Sequence member.

Modified: projects/clangbsd/contrib/llvm/include/llvm/CompilerDriver/CompilationGraph.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/CompilerDriver/CompilationGraph.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/CompilerDriver/CompilationGraph.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -43,7 +43,7 @@ namespace llvmc {
   class Edge : public llvm::RefCountedBaseVPTR<Edge> {
   public:
     Edge(const std::string& T) : ToolName_(T) {}
-    virtual ~Edge() {};
+    virtual ~Edge() {}
 
     const std::string& ToolName() const { return ToolName_; }
     virtual unsigned Weight(const InputLanguagesSet& InLangs) const = 0;

Modified: projects/clangbsd/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -149,7 +149,7 @@ public:
   /// CheckInvariants - For testing only.  Return true if all internal
   /// invariants are preserved, or return false and set ErrorStr to a helpful
   /// error message.
-  virtual bool CheckInvariants(std::string &ErrorStr) {
+  virtual bool CheckInvariants(std::string &) {
     return true;
   }
 

Modified: projects/clangbsd/contrib/llvm/include/llvm/Metadata.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/Metadata.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/Metadata.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -181,7 +181,7 @@ public:
   /// duplicates
   void Profile(FoldingSetNodeID &ID) const;
 
-  virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
+  virtual void replaceUsesOfWithOnConstant(Value *, Value *, Use *) {
     llvm_unreachable("This should never be called because MDNodes have no ops");
   }
 
@@ -291,7 +291,7 @@ public:
     return false;
   }
 
-  virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
+  virtual void replaceUsesOfWithOnConstant(Value *, Value *, Use *) {
     llvm_unreachable(
                 "This should never be called because NamedMDNodes have no ops");
   }
@@ -361,7 +361,7 @@ public:
 
   /// ValueIsDeleted - This handler is used to update metadata store
   /// when a value is deleted.
-  void ValueIsDeleted(const Value *V) {}
+  void ValueIsDeleted(const Value *) {}
   void ValueIsDeleted(const Instruction *Inst) {
     removeMDs(Inst);
   }

Modified: projects/clangbsd/contrib/llvm/include/llvm/Operator.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/Operator.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/Operator.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -57,8 +57,8 @@ public:
   }
 
   static inline bool classof(const Operator *) { return true; }
-  static inline bool classof(const Instruction *I) { return true; }
-  static inline bool classof(const ConstantExpr *I) { return true; }
+  static inline bool classof(const Instruction *) { return true; }
+  static inline bool classof(const ConstantExpr *) { return true; }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) || isa<ConstantExpr>(V);
   }

Modified: projects/clangbsd/contrib/llvm/include/llvm/Pass.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/Pass.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/Pass.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -276,7 +276,7 @@ public:
   /// doInitialization - Virtual method overridden by subclasses to do
   /// any necessary per-module initialization.
   ///
-  virtual bool doInitialization(Module &M) { return false; }
+  virtual bool doInitialization(Module &) { return false; }
   
   /// runOnFunction - Virtual method overriden by subclasses to do the
   /// per-function processing of the pass.
@@ -328,7 +328,7 @@ public:
   /// doInitialization - Virtual method overridden by subclasses to do
   /// any necessary per-module initialization.
   ///
-  virtual bool doInitialization(Module &M) { return false; }
+  virtual bool doInitialization(Module &) { return false; }
 
   /// doInitialization - Virtual method overridden by BasicBlockPass subclasses
   /// to do any necessary per-function initialization.

Modified: projects/clangbsd/contrib/llvm/include/llvm/Support/CommandLine.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/Support/CommandLine.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/Support/CommandLine.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -660,7 +660,7 @@ template<>
 class parser<std::string> : public basic_parser<std::string> {
 public:
   // parse - Return true on error.
-  bool parse(Option &, StringRef ArgName, StringRef Arg, std::string &Value) {
+  bool parse(Option &, StringRef, StringRef Arg, std::string &Value) {
     Value = Arg.str();
     return false;
   }
@@ -681,7 +681,7 @@ template<>
 class parser<char> : public basic_parser<char> {
 public:
   // parse - Return true on error.
-  bool parse(Option &, StringRef ArgName, StringRef Arg, char &Value) {
+  bool parse(Option &, StringRef, StringRef Arg, char &Value) {
     Value = Arg[0];
     return false;
   }

Modified: projects/clangbsd/contrib/llvm/include/llvm/Support/DebugLoc.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/Support/DebugLoc.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/Support/DebugLoc.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -29,10 +29,10 @@ namespace llvm {
     unsigned Line, Col;
 
     DebugLocTuple()
-      : Scope(0), InlinedAtLoc(0), Line(~0U), Col(~0U) {};
+      : Scope(0), InlinedAtLoc(0), Line(~0U), Col(~0U) {}
 
     DebugLocTuple(MDNode *n, MDNode *i, unsigned l, unsigned c)
-      : Scope(n), InlinedAtLoc(i), Line(l), Col(c) {};
+      : Scope(n), InlinedAtLoc(i), Line(l), Col(c) {}
 
     bool operator==(const DebugLocTuple &DLT) const {
       return Scope == DLT.Scope &&

Modified: projects/clangbsd/contrib/llvm/include/llvm/Support/raw_ostream.h
==============================================================================
--- projects/clangbsd/contrib/llvm/include/llvm/Support/raw_ostream.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/include/llvm/Support/raw_ostream.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -51,7 +51,7 @@ private:
   /// for a \see write_impl() call to handle the data which has been put into
   /// this buffer.
   char *OutBufStart, *OutBufEnd, *OutBufCur;
-  
+
   enum BufferKind {
     Unbuffered = 0,
     InternalBuffer,
@@ -211,7 +211,7 @@ public:
     return *this;
   }
 
-  raw_ostream &operator<<(double N);  
+  raw_ostream &operator<<(double N);
 
   /// write_hex - Output \arg N in hexadecimal, without any prefix or padding.
   raw_ostream &write_hex(unsigned long long N);
@@ -224,8 +224,8 @@ public:
 
   /// indent - Insert 'NumSpaces' spaces.
   raw_ostream &indent(unsigned NumSpaces);
-  
-  
+
+
   /// Changes the foreground color of text that will be output from this point
   /// forward.
   /// @param colors ANSI color to use, the special SAVEDCOLOR can be used to
@@ -233,8 +233,8 @@ public:
   /// @param bold bold/brighter text, default false
   /// @param bg if true change the background, default: change foreground
   /// @returns itself so it can be used within << invocations
-  virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
-                                   bool  bg=false) { return *this; }
+  virtual raw_ostream &changeColor(enum Colors, bool = false,
+				   bool = false) { return *this; }
 
   /// Resets the colors to terminal defaults. Call this when you are done
   /// outputting colored text, or before program exit.
@@ -253,7 +253,7 @@ private:
   /// write_impl - The is the piece of the class that is implemented
   /// by subclasses.  This writes the \args Size bytes starting at
   /// \arg Ptr to the underlying stream.
-  /// 
+  ///
   /// This function is guaranteed to only be called at a point at which it is
   /// safe for the subclass to install a new buffer via SetBuffer.
   ///
@@ -331,7 +331,7 @@ class raw_fd_ostream : public raw_ostrea
   virtual size_t preferred_buffer_size();
 
 public:
-  
+
   enum {
     /// F_Excl - When opening a file, this flag makes raw_fd_ostream
     /// report an error if the file already exists.
@@ -346,7 +346,7 @@ public:
     /// make this distinction.
     F_Binary = 4
   };
-  
+
   /// raw_fd_ostream - Open the specified file for writing. If an error occurs,
   /// information about the error is put into ErrorInfo, and the stream should
   /// be immediately destroyed; the string will be empty if no error occurred.
@@ -359,10 +359,10 @@ public:
 
   /// raw_fd_ostream ctor - FD is the file descriptor that this writes to.  If
   /// ShouldClose is true, this closes the file when the stream is destroyed.
-  raw_fd_ostream(int fd, bool shouldClose, 
-                 bool unbuffered=false) : raw_ostream(unbuffered), FD(fd), 
+  raw_fd_ostream(int fd, bool shouldClose,
+                 bool unbuffered=false) : raw_ostream(unbuffered), FD(fd),
                                           ShouldClose(shouldClose) {}
-  
+
   ~raw_fd_ostream();
 
   /// close - Manually flush the stream and close the file.
@@ -465,7 +465,7 @@ public:
 class raw_null_ostream : public raw_ostream {
   /// write_impl - See raw_ostream::write_impl.
   virtual void write_impl(const char *Ptr, size_t size);
-  
+
   /// current_pos - Return the current position within the stream, not
   /// counting the bytes currently in the buffer.
   virtual uint64_t current_pos();

Modified: projects/clangbsd/contrib/llvm/lib/Analysis/BasicAliasAnalysis.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/Analysis/BasicAliasAnalysis.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/Analysis/BasicAliasAnalysis.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -310,6 +310,28 @@ BasicAliasAnalysis::getModRefInfo(CallSi
     if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
       switch (II->getIntrinsicID()) {
       default: break;
+      case Intrinsic::memcpy:
+      case Intrinsic::memmove: {
+        unsigned Len = ~0U;
+        if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getOperand(3)))
+          Len = LenCI->getZExtValue();
+        Value *Dest = II->getOperand(1);
+        Value *Src = II->getOperand(2);
+        if (alias(Dest, Len, P, Size) == NoAlias) {
+          if (alias(Src, Len, P, Size) == NoAlias)
+            return NoModRef;
+          return Ref;
+        }
+        }
+        break;
+      case Intrinsic::memset:
+        if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getOperand(3))) {
+          unsigned Len = LenCI->getZExtValue();
+          Value *Dest = II->getOperand(1);
+          if (alias(Dest, Len, P, Size) == NoAlias)
+            return NoModRef;
+        }
+        break;
       case Intrinsic::atomic_cmp_swap:
       case Intrinsic::atomic_swap:
       case Intrinsic::atomic_load_add:
@@ -322,9 +344,25 @@ BasicAliasAnalysis::getModRefInfo(CallSi
       case Intrinsic::atomic_load_min:
       case Intrinsic::atomic_load_umax:
       case Intrinsic::atomic_load_umin:
-        if (alias(II->getOperand(1), Size, P, Size) == NoAlias)
-          return NoModRef;
+        if (TD) {
+          Value *Op1 = II->getOperand(1);
+          unsigned Op1Size = TD->getTypeStoreSize(Op1->getType());
+          if (alias(Op1, Op1Size, P, Size) == NoAlias)
+            return NoModRef;
+        }
         break;
+      case Intrinsic::lifetime_start:
+      case Intrinsic::lifetime_end:
+      case Intrinsic::invariant_start: {
+        unsigned PtrSize = cast<ConstantInt>(II->getOperand(1))->getZExtValue();
+        if (alias(II->getOperand(2), PtrSize, P, Size) == NoAlias)
+          return NoModRef;
+      }
+      case Intrinsic::invariant_end: {
+        unsigned PtrSize = cast<ConstantInt>(II->getOperand(2))->getZExtValue();
+        if (alias(II->getOperand(3), PtrSize, P, Size) == NoAlias)
+          return NoModRef;
+      }
       }
     }
   }

Modified: projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -145,7 +145,10 @@ class DbgConcreteScope;
 class VISIBILITY_HIDDEN DbgScope {
   DbgScope *Parent;                   // Parent to this scope.
   DIDescriptor Desc;                  // Debug info descriptor for scope.
-                                      // Either subprogram or block.
+                                      // FIXME use WeakVH for Desc.
+  WeakVH InlinedAt;                   // If this scope represents inlined
+                                      // function body then this is the location
+                                      // where this body is inlined.
   unsigned StartLabelID;              // Label ID of the beginning of scope.
   unsigned EndLabelID;                // Label ID of the end of scope.
   const MachineInstr *LastInsn;       // Last instruction of this scope.
@@ -157,14 +160,17 @@ class VISIBILITY_HIDDEN DbgScope {
   // Private state for dump()
   mutable unsigned IndentLevel;
 public:
-  DbgScope(DbgScope *P, DIDescriptor D)
-    : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), LastInsn(0),
-      FirstInsn(0), IndentLevel(0) {}
+  DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0)
+    : Parent(P), Desc(D), InlinedAt(I), StartLabelID(0), EndLabelID(0), 
+      LastInsn(0), FirstInsn(0), IndentLevel(0) {}
   virtual ~DbgScope();
 
   // Accessors.
   DbgScope *getParent()          const { return Parent; }
   DIDescriptor getDesc()         const { return Desc; }
+  MDNode *getInlinedAt()   const { 
+    return dyn_cast_or_null<MDNode>(InlinedAt); 
+  }
   unsigned getStartLabelID()     const { return StartLabelID; }
   unsigned getEndLabelID()       const { return EndLabelID; }
   SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
@@ -1296,29 +1302,39 @@ DIE *DwarfDebug::CreateDbgScopeVariable(
 
 /// getOrCreateScope - Returns the scope associated with the given descriptor.
 ///
-DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI) {
+DbgScope *DwarfDebug::getDbgScope(MDNode *N, const MachineInstr *MI,
+                                  MDNode *InlinedAt) {
   DbgScope *&Slot = DbgScopeMap[N];
   if (Slot) return Slot;
 
   DbgScope *Parent = NULL;
 
-  DIDescriptor Scope(N);
-  if (Scope.isCompileUnit()) {
-    return NULL;
-  } else if (Scope.isSubprogram()) {
-    DISubprogram SP(N);
-    DIDescriptor ParentDesc = SP.getContext();
-    if (!ParentDesc.isNull() && !ParentDesc.isCompileUnit())
-      Parent = getDbgScope(ParentDesc.getNode(), MI);
-  } else if (Scope.isLexicalBlock()) {
-    DILexicalBlock DB(N);
-    DIDescriptor ParentDesc = DB.getContext();
-    if (!ParentDesc.isNull())
-      Parent = getDbgScope(ParentDesc.getNode(), MI);
-  } else
-    assert (0 && "Unexpected scope info");
+  if (InlinedAt) {
+    DILocation IL(InlinedAt);
+    assert (!IL.isNull() && "Invalid InlindAt location!");
+    DenseMap<MDNode *, DbgScope *>::iterator DSI = 
+      DbgScopeMap.find(IL.getScope().getNode());
+    assert (DSI != DbgScopeMap.end() && "Unable to find InlineAt scope!");
+    Parent = DSI->second;
+  } else {
+    DIDescriptor Scope(N);
+    if (Scope.isCompileUnit()) {
+      return NULL;
+    } else if (Scope.isSubprogram()) {
+      DISubprogram SP(N);
+      DIDescriptor ParentDesc = SP.getContext();
+      if (!ParentDesc.isNull() && !ParentDesc.isCompileUnit())
+        Parent = getDbgScope(ParentDesc.getNode(), MI, InlinedAt);
+    } else if (Scope.isLexicalBlock()) {
+      DILexicalBlock DB(N);
+      DIDescriptor ParentDesc = DB.getContext();
+      if (!ParentDesc.isNull())
+        Parent = getDbgScope(ParentDesc.getNode(), MI, InlinedAt);
+    } else
+      assert (0 && "Unexpected scope info");
+  }
 
-  Slot = new DbgScope(Parent, DIDescriptor(N));
+  Slot = new DbgScope(Parent, DIDescriptor(N), InlinedAt);
   Slot->setFirstInsn(MI);
 
   if (Parent)
@@ -1795,7 +1811,10 @@ void DwarfDebug::CollectVariableInfo() {
     DIVariable DV (Var);
     if (DV.isNull()) continue;
     unsigned VSlot = VI->second;
-    DbgScope *Scope = getDbgScope(DV.getContext().getNode(),  NULL);
+    DenseMap<MDNode *, DbgScope *>::iterator DSI = 
+      DbgScopeMap.find(DV.getContext().getNode());
+    assert (DSI != DbgScopeMap.end() && "Unable to find variable scope!");
+    DbgScope *Scope = DSI->second;
     Scope->AddVariable(new DbgVariable(DV, VSlot, false));
   }
 }
@@ -1849,7 +1868,7 @@ bool DwarfDebug::ExtractScopeInformation
       // into a scope DIE at the end.
       DIDescriptor D(DLT.Scope);
       if (!D.isCompileUnit()) {
-        DbgScope *Scope = getDbgScope(DLT.Scope, MInsn);
+        DbgScope *Scope = getDbgScope(DLT.Scope, MInsn, DLT.InlinedAtLoc);
         Scope->setLastInsn(MInsn);
       }
     }

Modified: projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h	Thu Oct 15 13:29:27 2009	(r198130)
@@ -364,7 +364,7 @@ class VISIBILITY_HIDDEN DwarfDebug : pub
   /// getDbgScope - Returns the scope associated with the given descriptor.
   ///
   DbgScope *getOrCreateScope(MDNode *N);
-  DbgScope *getDbgScope(MDNode *N, const MachineInstr *MI);
+  DbgScope *getDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt);
 
   /// ConstructDbgScope - Construct the components of a scope.
   ///

Modified: projects/clangbsd/contrib/llvm/lib/CodeGen/CodePlacementOpt.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/CodeGen/CodePlacementOpt.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/CodeGen/CodePlacementOpt.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -24,7 +24,7 @@
 #include "llvm/ADT/Statistic.h"
 using namespace llvm;
 
-STATISTIC(NumHeaderAligned, "Number of loop header aligned");
+STATISTIC(NumLoopsAligned,  "Number of loops aligned");
 STATISTIC(NumIntraElim,     "Number of intra loop branches eliminated");
 STATISTIC(NumIntraMoved,    "Number of intra loop branches moved");
 
@@ -42,9 +42,6 @@ namespace {
     SmallVector<std::pair<MachineBasicBlock*,MachineBasicBlock*>, 4>
     UncondJmpMBBs;
 
-    /// LoopHeaders - A list of BBs which are loop headers.
-    SmallVector<MachineBasicBlock*, 4> LoopHeaders;
-
   public:
     static char ID;
     CodePlacementOpt() : MachineFunctionPass(&ID) {}
@@ -62,9 +59,8 @@ namespace {
 
   private:
     bool OptimizeIntraLoopEdges();
-    bool HeaderShouldBeAligned(MachineBasicBlock *MBB, MachineLoop *L,
-                               SmallPtrSet<MachineBasicBlock*, 4> &DoNotAlign);
     bool AlignLoops(MachineFunction &MF);
+    bool AlignLoop(MachineFunction &MF, MachineLoop *L, unsigned Align);
   };
 
   char CodePlacementOpt::ID = 0;
@@ -233,57 +229,12 @@ bool CodePlacementOpt::OptimizeIntraLoop
       ChangedMBBs.insert(FtMBB);
     }
     Changed = true;
-
-    // If BB is the loop latch, we may have a new loop headr.
-    if (MBB == L->getLoopLatch()) {
-      assert(MLI->isLoopHeader(SuccMBB) &&
-             "Only succ of loop latch is not the header?");
-      if (HasOneIntraSucc && IntraSucc)
-        std::replace(LoopHeaders.begin(),LoopHeaders.end(), SuccMBB, IntraSucc);
-    }
   }
 
   ++NumIntraMoved;
   return Changed;
 }
 
-/// HeaderShouldBeAligned - Return true if the specified loop header block
-/// should be aligned. For now, we will not align it if all the predcessors
-/// (i.e. loop back edges) are laid out above the header. FIXME: Do not
-/// align small loops.
-bool
-CodePlacementOpt::HeaderShouldBeAligned(MachineBasicBlock *MBB, MachineLoop *L,
-                               SmallPtrSet<MachineBasicBlock*, 4> &DoNotAlign) {
-  if (DoNotAlign.count(MBB))
-    return false;
-
-  bool BackEdgeBelow = false;
-  for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
-         PE = MBB->pred_end(); PI != PE; ++PI) {
-    MachineBasicBlock *PredMBB = *PI;
-    if (PredMBB == MBB || PredMBB->getNumber() > MBB->getNumber()) {
-      BackEdgeBelow = true;
-      break;
-    }
-  }
-
-  if (!BackEdgeBelow)
-    return false;
-
-  // Ok, we are going to align this loop header. If it's an inner loop,
-  // do not align its outer loop.
-  MachineBasicBlock *PreHeader = L->getLoopPreheader();
-  if (PreHeader) {
-    MachineLoop *L = MLI->getLoopFor(PreHeader);
-    if (L) {
-      MachineBasicBlock *HeaderBlock = L->getHeader();
-      HeaderBlock->setAlignment(0);
-      DoNotAlign.insert(HeaderBlock);
-    }
-  }
-  return true;
-}
-
 /// AlignLoops - Align loop headers to target preferred alignments.
 ///
 bool CodePlacementOpt::AlignLoops(MachineFunction &MF) {
@@ -295,26 +246,37 @@ bool CodePlacementOpt::AlignLoops(Machin
   if (!Align)
     return false;  // Don't care about loop alignment.
 
-  // Make sure blocks are numbered in order
-  MF.RenumberBlocks();
+  bool Changed = false;
+
+  for (MachineLoopInfo::iterator I = MLI->begin(), E = MLI->end();
+       I != E; ++I)
+    Changed |= AlignLoop(MF, *I, Align);
+
+  return Changed;
+}
 
+bool CodePlacementOpt::AlignLoop(MachineFunction &MF, MachineLoop *L,
+                                 unsigned Align) {
   bool Changed = false;
-  SmallPtrSet<MachineBasicBlock*, 4> DoNotAlign;
-  for (unsigned i = 0, e = LoopHeaders.size(); i != e; ++i) {
-    MachineBasicBlock *HeaderMBB = LoopHeaders[i];
-    MachineBasicBlock *PredMBB = prior(MachineFunction::iterator(HeaderMBB));
-    MachineLoop *L = MLI->getLoopFor(HeaderMBB);
-    if (L == MLI->getLoopFor(PredMBB))
-      // If previously BB is in the same loop, don't align this BB. We want
-      // to prevent adding noop's inside a loop.
-      continue;
-    if (HeaderShouldBeAligned(HeaderMBB, L, DoNotAlign)) {
-      HeaderMBB->setAlignment(Align);
-      Changed = true;
-      ++NumHeaderAligned;
-    }
+
+  // Do alignment for nested loops.
+  for (MachineLoop::iterator I = L->begin(), E = L->end(); I != E; ++I)
+    Changed |= AlignLoop(MF, *I, Align);
+
+  MachineBasicBlock *TopMBB = L->getHeader();
+  if (TopMBB == MF.begin()) return Changed;
+
+  MachineBasicBlock *PredMBB = prior(MachineFunction::iterator(TopMBB));
+  while (MLI->getLoopFor(PredMBB) == L) {
+    TopMBB = PredMBB;
+    if (TopMBB == MF.begin()) return Changed;
+    PredMBB = prior(MachineFunction::iterator(TopMBB));
   }
 
+  TopMBB->setAlignment(Align);
+  Changed = true;
+  ++NumLoopsAligned;
+
   return Changed;
 }
 
@@ -326,7 +288,7 @@ bool CodePlacementOpt::runOnMachineFunct
   TLI = MF.getTarget().getTargetLowering();
   TII = MF.getTarget().getInstrInfo();
 
-  // Analyze the BBs first and keep track of loop headers and BBs that
+  // Analyze the BBs first and keep track of BBs that
   // end with an unconditional jmp to another block in the same loop.
   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
     MachineBasicBlock *MBB = I;
@@ -335,8 +297,6 @@ bool CodePlacementOpt::runOnMachineFunct
     MachineLoop *L = MLI->getLoopFor(MBB);
     if (!L)
       continue;
-    if (MLI->isLoopHeader(MBB))
-      LoopHeaders.push_back(MBB);
 
     MachineBasicBlock *TBB = 0, *FBB = 0;
     SmallVector<MachineOperand, 4> Cond;
@@ -352,7 +312,6 @@ bool CodePlacementOpt::runOnMachineFunct
 
   ChangedMBBs.clear();
   UncondJmpMBBs.clear();
-  LoopHeaders.clear();
 
   return Changed;
 }

Modified: projects/clangbsd/contrib/llvm/lib/CodeGen/LiveVariables.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/CodeGen/LiveVariables.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/CodeGen/LiveVariables.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -323,10 +323,21 @@ bool LiveVariables::HandlePhysRegKill(un
       // The last partial def kills the register.
       LastPartDef->addOperand(MachineOperand::CreateReg(Reg, false/*IsDef*/,
                                                 true/*IsImp*/, true/*IsKill*/));
-    else
+    else {
+      MachineOperand *MO =
+        LastRefOrPartRef->findRegisterDefOperand(Reg, false, TRI);
+      bool NeedEC = MO->isEarlyClobber() && MO->getReg() != Reg;
       // If the last reference is the last def, then it's not used at all.
       // That is, unless we are currently processing the last reference itself.
       LastRefOrPartRef->addRegisterDead(Reg, TRI, true);
+      if (NeedEC) {
+        // If we are adding a subreg def and the superreg def is marked early
+        // clobber, add an early clobber marker to the subreg def.
+        MO = LastRefOrPartRef->findRegisterDefOperand(Reg);
+        if (MO)
+          MO->setIsEarlyClobber();
+      }
+    }
   } else if (!PhysRegUse[Reg]) {
     // Partial uses. Mark register def dead and add implicit def of
     // sub-registers which are used.

Modified: projects/clangbsd/contrib/llvm/lib/CodeGen/MachineInstr.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/CodeGen/MachineInstr.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/CodeGen/MachineInstr.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -212,17 +212,17 @@ void MachineOperand::print(raw_ostream &
         isEarlyClobber()) {
       OS << '<';
       bool NeedComma = false;
-      if (isImplicit()) {
-        if (NeedComma) OS << ',';
-        OS << (isDef() ? "imp-def" : "imp-use");
-        NeedComma = true;
-      } else if (isDef()) {
+      if (isDef()) {
         if (NeedComma) OS << ',';
         if (isEarlyClobber())
           OS << "earlyclobber,";
+        if (isImplicit())
+          OS << "imp-";
         OS << "def";
         NeedComma = true;
-      }
+      } else if (isImplicit())
+          OS << "imp-use";
+
       if (isKill() || isDead() || isUndef()) {
         if (NeedComma) OS << ',';
         if (isKill())  OS << "kill";

Modified: projects/clangbsd/contrib/llvm/lib/CodeGen/PrologEpilogInserter.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/CodeGen/PrologEpilogInserter.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/CodeGen/PrologEpilogInserter.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -767,7 +767,7 @@ void PEI::scavengeFrameVirtualRegs(Machi
     unsigned CurrentScratchReg = 0;
     bool havePrevValue = false;
     unsigned PrevScratchReg = 0;
-    int PrevValue;
+    int PrevValue = 0;
     MachineInstr *PrevLastUseMI = NULL;
     unsigned PrevLastUseOp = 0;
     bool trackingCurrentValue = false;
@@ -778,9 +778,7 @@ void PEI::scavengeFrameVirtualRegs(Machi
     // directly.
     for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
       MachineInstr *MI = I;
-      // Likewise, call getNumOperands() each iteration, as the MI may change
-      // inside the loop (with 'i' updated accordingly).
-      for (unsigned i = 0; i != MI->getNumOperands(); ++i)
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
         if (MI->getOperand(i).isReg()) {
           MachineOperand &MO = MI->getOperand(i);
           unsigned Reg = MO.getReg();
@@ -853,6 +851,7 @@ void PEI::scavengeFrameVirtualRegs(Machi
               // just calculating the value we already have.
               BB->erase(I, LastUseMI);
               MI = I = LastUseMI;
+              e = MI->getNumOperands();
 
               CurrentScratchReg = PrevScratchReg;
               // Extend the live range of the register

Modified: projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -74,16 +74,28 @@ namespace {
 
     /// CPUser - One user of a constant pool, keeping the machine instruction
     /// pointer, the constant pool being referenced, and the max displacement
-    /// allowed from the instruction to the CP.
+    /// allowed from the instruction to the CP.  The HighWaterMark records the
+    /// highest basic block where a new CPEntry can be placed.  To ensure this
+    /// pass terminates, the CP entries are initially placed at the end of the
+    /// function and then move monotonically to lower addresses.  The
+    /// exception to this rule is when the current CP entry for a particular
+    /// CPUser is out of range, but there is another CP entry for the same
+    /// constant value in range.  We want to use the existing in-range CP
+    /// entry, but if it later moves out of range, the search for new water
+    /// should resume where it left off.  The HighWaterMark is used to record
+    /// that point.
     struct CPUser {
       MachineInstr *MI;
       MachineInstr *CPEMI;
+      MachineBasicBlock *HighWaterMark;
       unsigned MaxDisp;
       bool NegOk;
       bool IsSoImm;
       CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp,
              bool neg, bool soimm)
-        : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp), NegOk(neg), IsSoImm(soimm) {}
+        : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp), NegOk(neg), IsSoImm(soimm) {
+        HighWaterMark = CPEMI->getParent();
+      }
     };
 
     /// CPUsers - Keep track of all of the machine instructions that use various
@@ -962,8 +974,8 @@ bool ARMConstantIslands::LookForWater(CP
          B = WaterList.begin();; --IP) {
     MachineBasicBlock* WaterBB = *IP;
     // Check if water is in range and at a lower address than the current one.
-    if (WaterIsInRange(UserOffset, WaterBB, U) &&
-        WaterBB->getNumber() < U.CPEMI->getParent()->getNumber()) {
+    if (WaterBB->getNumber() < U.HighWaterMark->getNumber() &&
+        WaterIsInRange(UserOffset, WaterBB, U)) {
       unsigned WBBId = WaterBB->getNumber();
       if (isThumb &&
           (BBOffsets[WBBId] + BBSizes[WBBId])%4 != 0) {
@@ -1006,14 +1018,12 @@ void ARMConstantIslands::CreateNewWater(
                                BBSizes[UserMBB->getNumber()];
   assert(OffsetOfNextBlock== BBOffsets[UserMBB->getNumber()+1]);
 
-  // If the use is at the end of the block, or the end of the block
-  // is within range, make new water there.  (The addition below is
-  // for the unconditional branch we will be adding:  4 bytes on ARM + Thumb2,
-  // 2 on Thumb1.  Possible Thumb1 alignment padding is allowed for
+  // If the block does not end in an unconditional branch already, and if the
+  // end of the block is within range, make new water there.  (The addition
+  // below is for the unconditional branch we will be adding: 4 bytes on ARM +
+  // Thumb2, 2 on Thumb1.  Possible Thumb1 alignment padding is allowed for
   // inside OffsetIsInRange.
-  // If the block ends in an unconditional branch already, it is water,
-  // and is known to be out of range, so we'll always be adding a branch.)
-  if (&UserMBB->back() == UserMI ||
+  if (BBHasFallthrough(UserMBB) &&
       OffsetIsInRange(UserOffset, OffsetOfNextBlock + (isThumb1 ? 2: 4),
                       U.MaxDisp, U.NegOk, U.IsSoImm)) {
     DEBUG(errs() << "Split at end of block\n");
@@ -1131,6 +1141,7 @@ bool ARMConstantIslands::HandleConstantP
 
   // Now that we have an island to add the CPE to, clone the original CPE and
   // add it to the island.
+  U.HighWaterMark = NewIsland;
   U.CPEMI = BuildMI(NewIsland, DebugLoc::getUnknownLoc(),
                     TII->get(ARM::CONSTPOOL_ENTRY))
                 .addImm(ID).addConstantPoolIndex(CPI).addImm(Size);

Modified: projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
==============================================================================
--- projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp	Thu Oct 15 13:18:43 2009	(r198129)
+++ projects/clangbsd/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp	Thu Oct 15 13:29:27 2009	(r198130)
@@ -133,6 +133,13 @@ private:
   SDNode *SelectVLD(SDValue Op, unsigned NumVecs, unsigned *DOpcodes,
                     unsigned *QOpcodes0, unsigned *QOpcodes1);
 
+  /// SelectVST - Select NEON store intrinsics.  NumVecs should
+  /// be 2, 3 or 4.  The opcode arrays specify the instructions used for
+  /// stores of D registers and even subregs and odd subregs of Q registers.
+  /// For NumVecs == 2, QOpcodes1 is not used.
+  SDNode *SelectVST(SDValue Op, unsigned NumVecs, unsigned *DOpcodes,
+                    unsigned *QOpcodes0, unsigned *QOpcodes1);
+
   /// SelectVLDSTLane - Select NEON load/store lane intrinsics.  NumVecs should
   /// be 2, 3 or 4.  The opcode arrays specify the instructions used for
   /// load/store of D registers and even subregs and odd subregs of Q registers.
@@ -1063,13 +1070,13 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDVal
     ResTys.push_back(MemAddr.getValueType());
     ResTys.push_back(MVT::Other);
 
-    // Load the even subreg.
+    // Load the even subregs.
     unsigned Opc = QOpcodes0[OpcodeIndex];
     const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Chain };
     SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 4);
     Chain = SDValue(VLdA, NumVecs+1);
 
-    // Load the odd subreg.
+    // Load the odd subregs.
     Opc = QOpcodes1[OpcodeIndex];
     const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, MemOpc, Chain };
     SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 4);
@@ -1085,6 +1092,95 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDVal
   return NULL;
 }
 
+SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs,
+                                   unsigned *DOpcodes, unsigned *QOpcodes0,
+                                   unsigned *QOpcodes1) {
+  assert(NumVecs >=2 && NumVecs <= 4 && "VST NumVecs out-of-range");
+  SDNode *N = Op.getNode();
+  DebugLoc dl = N->getDebugLoc();
+
+  SDValue MemAddr, MemUpdate, MemOpc;
+  if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc))
+    return NULL;
+
+  SDValue Chain = N->getOperand(0);
+  EVT VT = N->getOperand(3).getValueType();
+  bool is64BitVector = VT.is64BitVector();
+
+  unsigned OpcodeIndex;
+  switch (VT.getSimpleVT().SimpleTy) {
+  default: llvm_unreachable("unhandled vst type");
+    // Double-register operations:
+  case MVT::v8i8:  OpcodeIndex = 0; break;
+  case MVT::v4i16: OpcodeIndex = 1; break;
+  case MVT::v2f32:
+  case MVT::v2i32: OpcodeIndex = 2; break;
+  case MVT::v1i64: OpcodeIndex = 3; break;
+    // Quad-register operations:
+  case MVT::v16i8: OpcodeIndex = 0; break;
+  case MVT::v8i16: OpcodeIndex = 1; break;
+  case MVT::v4f32:
+  case MVT::v4i32: OpcodeIndex = 2; break;
+  }
+
+  SmallVector<SDValue, 8> Ops;
+  Ops.push_back(MemAddr);
+  Ops.push_back(MemUpdate);
+  Ops.push_back(MemOpc);
+
+  if (is64BitVector) {
+    unsigned Opc = DOpcodes[OpcodeIndex];
+    for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
+      Ops.push_back(N->getOperand(Vec+3));
+    Ops.push_back(Chain);
+    return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+4);
+  }
+
+  EVT RegVT = GetNEONSubregVT(VT);
+  if (NumVecs == 2) {
+    // Quad registers are directly supported for VST2,
+    // storing 2 pairs of D regs.
+    unsigned Opc = QOpcodes0[OpcodeIndex];
+    for (unsigned Vec = 0; Vec < NumVecs; ++Vec) {
+      Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
+                                                   N->getOperand(Vec+3)));
+      Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
+                                                   N->getOperand(Vec+3)));
+    }
+    Ops.push_back(Chain);
+    return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 8);
+  }
+
+  // Otherwise, quad registers are stored with two separate instructions,
+  // where one stores the even registers and the other stores the odd registers.
+
+  // Enable writeback to the address register.
+  MemOpc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(true), MVT::i32);
+
+  // Store the even subregs.
+  for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
+    Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
+                                                 N->getOperand(Vec+3)));
+  Ops.push_back(Chain);
+  unsigned Opc = QOpcodes0[OpcodeIndex];
+  SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
+                                        MVT::Other, Ops.data(), NumVecs+4);
+  Chain = SDValue(VStA, 1);
+
+  // Store the odd subregs.
+  Ops[0] = SDValue(VStA, 0); // MemAddr
+  for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
+    Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
+                                                N->getOperand(Vec+3));
+  Ops[NumVecs+3] = Chain;
+  Opc = QOpcodes1[OpcodeIndex];
+  SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
+                                        MVT::Other, Ops.data(), NumVecs+4);
+  Chain = SDValue(VStB, 1);
+  ReplaceUses(SDValue(N, 0), Chain);
+  return NULL;
+}
+
 SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDValue Op, bool IsLoad,
                                          unsigned NumVecs, unsigned *DOpcodes,
                                          unsigned *QOpcodes0,
@@ -1612,9 +1708,6 @@ SDNode *ARMDAGToDAGISel::Select(SDValue 
   case ISD::INTRINSIC_VOID:
   case ISD::INTRINSIC_W_CHAIN: {
     unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
-    EVT VT = N->getValueType(0);
-    unsigned Opc = 0;
-
     switch (IntNo) {
     default:
       break;
@@ -1664,178 +1757,26 @@ SDNode *ARMDAGToDAGISel::Select(SDValue 
     }
 
     case Intrinsic::arm_neon_vst2: {
-      SDValue MemAddr, MemUpdate, MemOpc;
-      if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc))
-        return NULL;
-      SDValue Chain = N->getOperand(0);
-      VT = N->getOperand(3).getValueType();
-      if (VT.is64BitVector()) {
-        switch (VT.getSimpleVT().SimpleTy) {
-        default: llvm_unreachable("unhandled vst2 type");
-        case MVT::v8i8:  Opc = ARM::VST2d8; break;
-        case MVT::v4i16: Opc = ARM::VST2d16; break;
-        case MVT::v2f32:
-        case MVT::v2i32: Opc = ARM::VST2d32; break;
-        case MVT::v1i64: Opc = ARM::VST2d64; break;
-        }
-        const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc,
-                                N->getOperand(3), N->getOperand(4), Chain };
-        return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops, 6);
-      }
-      // Quad registers are stored as pairs of double registers.
-      EVT RegVT;
-      switch (VT.getSimpleVT().SimpleTy) {
-      default: llvm_unreachable("unhandled vst2 type");
-      case MVT::v16i8: Opc = ARM::VST2q8; RegVT = MVT::v8i8; break;
-      case MVT::v8i16: Opc = ARM::VST2q16; RegVT = MVT::v4i16; break;
-      case MVT::v4f32: Opc = ARM::VST2q32; RegVT = MVT::v2f32; break;
-      case MVT::v4i32: Opc = ARM::VST2q32; RegVT = MVT::v2i32; break;
-      }
-      SDValue D0 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
-                                                  N->getOperand(3));
-      SDValue D1 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
-                                                  N->getOperand(3));
-      SDValue D2 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
-                                                  N->getOperand(4));
-      SDValue D3 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
-                                                  N->getOperand(4));
-      const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc,
-                              D0, D1, D2, D3, Chain };
-      return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops, 8);
+      unsigned DOpcodes[] = { ARM::VST2d8, ARM::VST2d16,
+                              ARM::VST2d32, ARM::VST2d64 };
+      unsigned QOpcodes[] = { ARM::VST2q8, ARM::VST2q16, ARM::VST2q32 };
+      return SelectVST(Op, 2, DOpcodes, QOpcodes, 0);
     }
 
     case Intrinsic::arm_neon_vst3: {
-      SDValue MemAddr, MemUpdate, MemOpc;
-      if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc))
-        return NULL;
-      SDValue Chain = N->getOperand(0);
-      VT = N->getOperand(3).getValueType();
-      if (VT.is64BitVector()) {
-        switch (VT.getSimpleVT().SimpleTy) {
-        default: llvm_unreachable("unhandled vst3 type");
-        case MVT::v8i8:  Opc = ARM::VST3d8; break;
-        case MVT::v4i16: Opc = ARM::VST3d16; break;
-        case MVT::v2f32:
-        case MVT::v2i32: Opc = ARM::VST3d32; break;
-        case MVT::v1i64: Opc = ARM::VST3d64; break;
-        }
-        const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc,
-                                N->getOperand(3), N->getOperand(4),
-                                N->getOperand(5), Chain };
-        return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops, 7);
-      }
-      // Quad registers are stored with two separate instructions, where one
-      // stores the even registers and the other stores the odd registers.
-      EVT RegVT;
-      unsigned Opc2 = 0;
-      switch (VT.getSimpleVT().SimpleTy) {
-      default: llvm_unreachable("unhandled vst3 type");
-      case MVT::v16i8:
-        Opc = ARM::VST3q8a;  Opc2 = ARM::VST3q8b;  RegVT = MVT::v8i8; break;
-      case MVT::v8i16:
-        Opc = ARM::VST3q16a; Opc2 = ARM::VST3q16b; RegVT = MVT::v4i16; break;
-      case MVT::v4f32:
-        Opc = ARM::VST3q32a; Opc2 = ARM::VST3q32b; RegVT = MVT::v2f32; break;
-      case MVT::v4i32:
-        Opc = ARM::VST3q32a; Opc2 = ARM::VST3q32b; RegVT = MVT::v2i32; break;
-      }
-      // Enable writeback to the address register.
-      MemOpc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(true), MVT::i32);
-
-      SDValue D0 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
-                                                  N->getOperand(3));
-      SDValue D2 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
-                                                  N->getOperand(4));
-      SDValue D4 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
-                                                  N->getOperand(5));
-      const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, D0, D2, D4, Chain };
-      SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
-                                            MVT::Other, OpsA, 7);
-      Chain = SDValue(VStA, 1);
-
-      SDValue D1 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
-                                                  N->getOperand(3));
-      SDValue D3 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
-                                                  N->getOperand(4));
-      SDValue D5 = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
-                                                  N->getOperand(5));
-      MemAddr = SDValue(VStA, 0);
-      const SDValue OpsB[] = { MemAddr, MemUpdate, MemOpc, D1, D3, D5, Chain };
-      SDNode *VStB = CurDAG->getMachineNode(Opc2, dl, MemAddr.getValueType(),
-                                            MVT::Other, OpsB, 7);
-      Chain = SDValue(VStB, 1);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list