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