summaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/PostOrderIterator.h7
-rw-r--r--include/llvm/ADT/Triple.h1
-rw-r--r--include/llvm/Analysis/IVUsers.h23
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h110
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h67
-rw-r--r--include/llvm/CallingConv.h13
-rw-r--r--include/llvm/CodeGen/FastISel.h1
-rw-r--r--include/llvm/CodeGen/LiveInterval.h148
-rw-r--r--include/llvm/CodeGen/MachineFunction.h2
-rw-r--r--include/llvm/CodeGen/MachineInstr.h4
-rw-r--r--include/llvm/CodeGen/MachineOperand.h18
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h29
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h4
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h2
-rw-r--r--include/llvm/Config/AsmPrinters.def.in29
-rw-r--r--include/llvm/Config/Targets.def.in28
-rw-r--r--include/llvm/Config/config.h.cmake3
-rw-r--r--include/llvm/Config/config.h.in6
-rw-r--r--include/llvm/Constants.h34
-rw-r--r--include/llvm/DerivedTypes.h4
-rw-r--r--include/llvm/MC/MCInst.h125
-rw-r--r--include/llvm/Support/CommandLine.h4
-rw-r--r--include/llvm/Support/DebugLoc.h (renamed from include/llvm/CodeGen/DebugLoc.h)12
-rw-r--r--include/llvm/Support/IRBuilder.h8
-rw-r--r--include/llvm/Support/ManagedStatic.h16
-rw-r--r--include/llvm/Support/SourceMgr.h120
-rw-r--r--include/llvm/System/Atomic.h2
-rw-r--r--include/llvm/System/Mutex.h80
-rw-r--r--include/llvm/System/Path.h5
-rw-r--r--include/llvm/System/RWMutex.h175
-rw-r--r--include/llvm/System/Threading.h45
-rw-r--r--include/llvm/Target/DarwinTargetAsmInfo.h2
-rw-r--r--include/llvm/Target/Target.td1
-rw-r--r--include/llvm/Target/TargetAsmInfo.h26
-rw-r--r--include/llvm/Target/TargetLowering.h2
-rw-r--r--include/llvm/Target/TargetMachine.h8
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h30
-rw-r--r--include/llvm/Target/TargetSelect.h65
-rw-r--r--include/llvm/Transforms/Scalar.h8
-rw-r--r--include/llvm/Transforms/Utils/Local.h10
-rw-r--r--include/llvm/Type.h36
41 files changed, 1139 insertions, 174 deletions
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index bf7ce9d0bb6aa..b477d0a8f0f52 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include <set>
#include <stack>
#include <vector>
@@ -39,9 +40,9 @@ public:
};
template<class GraphT,
- class SetType = std::set<typename GraphTraits<GraphT>::NodeType*>,
- bool ExtStorage = false,
- class GT = GraphTraits<GraphT> >
+ class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+ bool ExtStorage = false,
+ class GT = GraphTraits<GraphT> >
class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
public po_iterator_storage<SetType, ExtStorage> {
typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index b260f984948ed..b3f742e0a59bb 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -49,6 +49,7 @@ public:
enum OSType {
UnknownOS,
+ AuroraUX,
Darwin,
DragonFly,
FreeBSD,
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index 36ff07b678e60..ac785d5c54a92 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -35,9 +35,9 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
public:
IVStrideUse(IVUsersOfOneStride *parent,
const SCEVHandle &offset,
- Instruction* U, Value *O, bool issigned)
+ Instruction* U, Value *O)
: CallbackVH(U), Parent(parent), Offset(offset),
- OperandValToReplace(O), IsSigned(issigned),
+ OperandValToReplace(O),
IsUseOfPostIncrementedValue(false) {
}
@@ -57,8 +57,7 @@ public:
/// getOffset - Return the offset to add to a theoeretical induction
/// variable that starts at zero and counts up by the stride to compute
- /// the value for the use. This always has the same type as the stride,
- /// which may need to be casted to match the type of the use.
+ /// the value for the use. This always has the same type as the stride.
SCEVHandle getOffset() const { return Offset; }
/// setOffset - Assign a new offset to this use.
@@ -78,13 +77,6 @@ public:
OperandValToReplace = Op;
}
- /// isSigned - The stride (and thus also the Offset) of this use may be in
- /// a narrower type than the use itself (OperandValToReplace->getType()).
- /// When this is the case, isSigned() indicates whether the IV expression
- /// should be signed-extended instead of zero-extended to fit the type of
- /// the use.
- bool isSigned() const { return IsSigned; }
-
/// isUseOfPostIncrementedValue - True if this should use the
/// post-incremented version of this IV, not the preincremented version.
/// This can only be set in special cases, such as the terminating setcc
@@ -110,10 +102,6 @@ private:
/// that this IVStrideUse is representing.
WeakVH OperandValToReplace;
- /// IsSigned - Determines whether the replacement value is sign or
- /// zero extended to the type of the use.
- bool IsSigned;
-
/// IsUseOfPostIncrementedValue - True if this should use the
/// post-incremented version of this IV, not the preincremented version.
bool IsUseOfPostIncrementedValue;
@@ -170,9 +158,8 @@ public:
/// initial value and the operand that uses the IV.
ilist<IVStrideUse> Users;
- void addUser(const SCEVHandle &Offset,Instruction *User, Value *Operand,
- bool isSigned) {
- Users.push_back(new IVStrideUse(this, Offset, User, Operand, isSigned));
+ void addUser(const SCEVHandle &Offset, Instruction *User, Value *Operand) {
+ Users.push_back(new IVStrideUse(this, Offset, User, Operand));
}
};
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 41725be1ca3ec..8d5136cea2c3f 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -25,6 +25,7 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ValueHandle.h"
+#include "llvm/ADT/DenseMap.h"
#include <iosfwd>
namespace llvm {
@@ -34,6 +35,7 @@ namespace llvm {
class SCEVHandle;
class ScalarEvolution;
class TargetData;
+ template<> struct DenseMapInfo<SCEVHandle>;
/// SCEV - This class represents an analyzed expression in the program. These
/// are reference-counted opaque objects that the client is not allowed to
@@ -44,18 +46,22 @@ namespace llvm {
mutable unsigned RefCount;
friend class SCEVHandle;
+ friend class DenseMapInfo<SCEVHandle>;
void addRef() const { ++RefCount; }
void dropRef() const {
if (--RefCount == 0)
delete this;
}
+ const ScalarEvolution* parent;
+
SCEV(const SCEV &); // DO NOT IMPLEMENT
void operator=(const SCEV &); // DO NOT IMPLEMENT
protected:
virtual ~SCEV();
public:
- explicit SCEV(unsigned SCEVTy) : SCEVType(SCEVTy), RefCount(0) {}
+ explicit SCEV(unsigned SCEVTy, const ScalarEvolution* p) :
+ SCEVType(SCEVTy), RefCount(0), parent(p) {}
unsigned getSCEVType() const { return SCEVType; }
@@ -123,7 +129,7 @@ namespace llvm {
/// None of the standard SCEV operations are valid on this class, it is just a
/// marker.
struct SCEVCouldNotCompute : public SCEV {
- SCEVCouldNotCompute();
+ SCEVCouldNotCompute(const ScalarEvolution* p);
~SCEVCouldNotCompute();
// None of these methods are valid for this object.
@@ -197,6 +203,31 @@ namespace llvm {
template<> struct simplify_type<SCEVHandle>
: public simplify_type<const SCEVHandle> {};
+ // Specialize DenseMapInfo for SCEVHandle so that SCEVHandle may be used
+ // as a key in DenseMaps.
+ template<>
+ struct DenseMapInfo<SCEVHandle> {
+ static inline SCEVHandle getEmptyKey() {
+ static SCEVCouldNotCompute Empty(0);
+ if (Empty.RefCount == 0)
+ Empty.addRef();
+ return &Empty;
+ }
+ static inline SCEVHandle getTombstoneKey() {
+ static SCEVCouldNotCompute Tombstone(0);
+ if (Tombstone.RefCount == 0)
+ Tombstone.addRef();
+ return &Tombstone;
+ }
+ static unsigned getHashValue(const SCEVHandle &Val) {
+ return DenseMapInfo<const SCEV *>::getHashValue(Val);
+ }
+ static bool isEqual(const SCEVHandle &LHS, const SCEVHandle &RHS) {
+ return LHS == RHS;
+ }
+ static bool isPod() { return false; }
+ };
+
/// ScalarEvolution - This class is the main scalar evolution driver. Because
/// client code (intentionally) can't do much with the SCEV objects directly,
/// they must ask this class for services.
@@ -301,6 +332,13 @@ namespace llvm {
const SCEVHandle &SymName,
const SCEVHandle &NewVal);
+ /// getBECount - Subtract the end and start values and divide by the step,
+ /// rounding up, to get the number of times the backedge is executed. Return
+ /// CouldNotCompute if an intermediate computation overflows.
+ SCEVHandle getBECount(const SCEVHandle &Start,
+ const SCEVHandle &End,
+ const SCEVHandle &Step);
+
/// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
/// loop, lazily computing new values if the loop hasn't been analyzed
/// yet.
@@ -310,6 +348,31 @@ namespace llvm {
/// loop will iterate.
BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L);
+ /// ComputeBackedgeTakenCountFromExit - Compute the number of times the
+ /// backedge of the specified loop will execute if it exits via the
+ /// specified block.
+ BackedgeTakenInfo ComputeBackedgeTakenCountFromExit(const Loop *L,
+ BasicBlock *ExitingBlock);
+
+ /// ComputeBackedgeTakenCountFromExitCond - Compute the number of times the
+ /// backedge of the specified loop will execute if its exit condition
+ /// were a conditional branch of ExitCond, TBB, and FBB.
+ BackedgeTakenInfo
+ ComputeBackedgeTakenCountFromExitCond(const Loop *L,
+ Value *ExitCond,
+ BasicBlock *TBB,
+ BasicBlock *FBB);
+
+ /// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of
+ /// times the backedge of the specified loop will execute if its exit
+ /// condition were a conditional branch of the ICmpInst ExitCond, TBB,
+ /// and FBB.
+ BackedgeTakenInfo
+ ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L,
+ ICmpInst *ExitCond,
+ BasicBlock *TBB,
+ BasicBlock *FBB);
+
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition
/// of 'icmp op load X, cst', try to see if we can compute the trip count.
SCEVHandle
@@ -390,28 +453,29 @@ namespace llvm {
SCEVHandle getConstant(ConstantInt *V);
SCEVHandle getConstant(const APInt& Val);
+ SCEVHandle getConstant(const Type *Ty, uint64_t V, bool isSigned = false);
SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty);
SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty);
SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty);
SCEVHandle getAnyExtendExpr(const SCEVHandle &Op, const Type *Ty);
- SCEVHandle getAddExpr(std::vector<SCEVHandle> &Ops);
+ SCEVHandle getAddExpr(SmallVectorImpl<SCEVHandle> &Ops);
SCEVHandle getAddExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) {
- std::vector<SCEVHandle> Ops;
+ SmallVector<SCEVHandle, 2> Ops;
Ops.push_back(LHS);
Ops.push_back(RHS);
return getAddExpr(Ops);
}
SCEVHandle getAddExpr(const SCEVHandle &Op0, const SCEVHandle &Op1,
const SCEVHandle &Op2) {
- std::vector<SCEVHandle> Ops;
+ SmallVector<SCEVHandle, 3> Ops;
Ops.push_back(Op0);
Ops.push_back(Op1);
Ops.push_back(Op2);
return getAddExpr(Ops);
}
- SCEVHandle getMulExpr(std::vector<SCEVHandle> &Ops);
+ SCEVHandle getMulExpr(SmallVectorImpl<SCEVHandle> &Ops);
SCEVHandle getMulExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) {
- std::vector<SCEVHandle> Ops;
+ SmallVector<SCEVHandle, 2> Ops;
Ops.push_back(LHS);
Ops.push_back(RHS);
return getMulExpr(Ops);
@@ -419,17 +483,19 @@ namespace llvm {
SCEVHandle getUDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
SCEVHandle getAddRecExpr(const SCEVHandle &Start, const SCEVHandle &Step,
const Loop *L);
- SCEVHandle getAddRecExpr(std::vector<SCEVHandle> &Operands,
+ SCEVHandle getAddRecExpr(SmallVectorImpl<SCEVHandle> &Operands,
const Loop *L);
- SCEVHandle getAddRecExpr(const std::vector<SCEVHandle> &Operands,
+ SCEVHandle getAddRecExpr(const SmallVectorImpl<SCEVHandle> &Operands,
const Loop *L) {
- std::vector<SCEVHandle> NewOp(Operands);
+ SmallVector<SCEVHandle, 4> NewOp(Operands.begin(), Operands.end());
return getAddRecExpr(NewOp, L);
}
SCEVHandle getSMaxExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
- SCEVHandle getSMaxExpr(std::vector<SCEVHandle> Operands);
+ SCEVHandle getSMaxExpr(SmallVectorImpl<SCEVHandle> &Operands);
SCEVHandle getUMaxExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
- SCEVHandle getUMaxExpr(std::vector<SCEVHandle> Operands);
+ SCEVHandle getUMaxExpr(SmallVectorImpl<SCEVHandle> &Operands);
+ SCEVHandle getSMinExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
+ SCEVHandle getUMinExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
SCEVHandle getUnknown(Value *V);
SCEVHandle getCouldNotCompute();
@@ -481,6 +547,12 @@ namespace llvm {
/// specified signed integer value and return a SCEV for the constant.
SCEVHandle getIntegerSCEV(int Val, const Type *Ty);
+ /// getUMaxFromMismatchedTypes - Promote the operands to the wider of
+ /// the types using zero-extension, and then perform a umax operation
+ /// with them.
+ SCEVHandle getUMaxFromMismatchedTypes(const SCEVHandle &LHS,
+ const SCEVHandle &RHS);
+
/// hasSCEV - Return true if the SCEV for this value has already been
/// computed.
bool hasSCEV(Value *V) const;
@@ -539,6 +611,20 @@ namespace llvm {
/// is deleted.
void forgetLoopBackedgeTakenCount(const Loop *L);
+ /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
+ /// guaranteed to end in (at every loop iteration). It is, at the same time,
+ /// the minimum number of times S is divisible by 2. For example, given {4,+,8}
+ /// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S.
+ uint32_t GetMinTrailingZeros(const SCEVHandle &S);
+
+ /// GetMinLeadingZeros - Determine the minimum number of zero bits that S is
+ /// guaranteed to begin with (at every loop iteration).
+ uint32_t GetMinLeadingZeros(const SCEVHandle &S);
+
+ /// GetMinSignBits - Determine the minimum number of sign bits that S is
+ /// guaranteed to begin with.
+ uint32_t GetMinSignBits(const SCEVHandle &S);
+
virtual bool runOnFunction(Function &F);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 1978055b1af6d..28423569d2e38 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -36,7 +36,8 @@ namespace llvm {
friend class ScalarEvolution;
ConstantInt *V;
- explicit SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {}
+ explicit SCEVConstant(ConstantInt *v, const ScalarEvolution* p) :
+ SCEV(scConstant, p), V(v) {}
virtual ~SCEVConstant();
public:
@@ -79,7 +80,8 @@ namespace llvm {
SCEVHandle Op;
const Type *Ty;
- SCEVCastExpr(unsigned SCEVTy, const SCEVHandle &op, const Type *ty);
+ SCEVCastExpr(unsigned SCEVTy, const SCEVHandle &op, const Type *ty,
+ const ScalarEvolution* p);
virtual ~SCEVCastExpr();
public:
@@ -112,7 +114,8 @@ namespace llvm {
class SCEVTruncateExpr : public SCEVCastExpr {
friend class ScalarEvolution;
- SCEVTruncateExpr(const SCEVHandle &op, const Type *ty);
+ SCEVTruncateExpr(const SCEVHandle &op, const Type *ty,
+ const ScalarEvolution* p);
virtual ~SCEVTruncateExpr();
public:
@@ -141,7 +144,8 @@ namespace llvm {
class SCEVZeroExtendExpr : public SCEVCastExpr {
friend class ScalarEvolution;
- SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty);
+ SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty,
+ const ScalarEvolution* p);
virtual ~SCEVZeroExtendExpr();
public:
@@ -170,7 +174,8 @@ namespace llvm {
class SCEVSignExtendExpr : public SCEVCastExpr {
friend class ScalarEvolution;
- SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty);
+ SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty,
+ const ScalarEvolution* p);
virtual ~SCEVSignExtendExpr();
public:
@@ -199,10 +204,11 @@ namespace llvm {
///
class SCEVNAryExpr : public SCEV {
protected:
- std::vector<SCEVHandle> Operands;
+ SmallVector<SCEVHandle, 8> Operands;
- SCEVNAryExpr(enum SCEVTypes T, const std::vector<SCEVHandle> &ops)
- : SCEV(T), Operands(ops) {}
+ SCEVNAryExpr(enum SCEVTypes T, const SmallVectorImpl<SCEVHandle> &ops,
+ const ScalarEvolution* p)
+ : SCEV(T, p), Operands(ops.begin(), ops.end()) {}
virtual ~SCEVNAryExpr() {}
public:
@@ -212,8 +218,8 @@ namespace llvm {
return Operands[i];
}
- const std::vector<SCEVHandle> &getOperands() const { return Operands; }
- typedef std::vector<SCEVHandle>::const_iterator op_iterator;
+ const SmallVectorImpl<SCEVHandle> &getOperands() const { return Operands; }
+ typedef SmallVectorImpl<SCEVHandle>::const_iterator op_iterator;
op_iterator op_begin() const { return Operands.begin(); }
op_iterator op_end() const { return Operands.end(); }
@@ -259,8 +265,10 @@ namespace llvm {
///
class SCEVCommutativeExpr : public SCEVNAryExpr {
protected:
- SCEVCommutativeExpr(enum SCEVTypes T, const std::vector<SCEVHandle> &ops)
- : SCEVNAryExpr(T, ops) {}
+ SCEVCommutativeExpr(enum SCEVTypes T,
+ const SmallVectorImpl<SCEVHandle> &ops,
+ const ScalarEvolution* p)
+ : SCEVNAryExpr(T, ops, p) {}
~SCEVCommutativeExpr();
public:
@@ -289,8 +297,9 @@ namespace llvm {
class SCEVAddExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
- explicit SCEVAddExpr(const std::vector<SCEVHandle> &ops)
- : SCEVCommutativeExpr(scAddExpr, ops) {
+ explicit SCEVAddExpr(const SmallVectorImpl<SCEVHandle> &ops,
+ const ScalarEvolution* p)
+ : SCEVCommutativeExpr(scAddExpr, ops, p) {
}
public:
@@ -309,8 +318,9 @@ namespace llvm {
class SCEVMulExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
- explicit SCEVMulExpr(const std::vector<SCEVHandle> &ops)
- : SCEVCommutativeExpr(scMulExpr, ops) {
+ explicit SCEVMulExpr(const SmallVectorImpl<SCEVHandle> &ops,
+ const ScalarEvolution* p)
+ : SCEVCommutativeExpr(scMulExpr, ops, p) {
}
public:
@@ -331,8 +341,9 @@ namespace llvm {
friend class ScalarEvolution;
SCEVHandle LHS, RHS;
- SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs)
- : SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {}
+ SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs,
+ const ScalarEvolution* p)
+ : SCEV(scUDivExpr, p), LHS(lhs), RHS(rhs) {}
virtual ~SCEVUDivExpr();
public:
@@ -387,8 +398,9 @@ namespace llvm {
const Loop *L;
- SCEVAddRecExpr(const std::vector<SCEVHandle> &ops, const Loop *l)
- : SCEVNAryExpr(scAddRecExpr, ops), L(l) {
+ SCEVAddRecExpr(const SmallVectorImpl<SCEVHandle> &ops, const Loop *l,
+ const ScalarEvolution* p)
+ : SCEVNAryExpr(scAddRecExpr, ops, p), L(l) {
for (size_t i = 0, e = Operands.size(); i != e; ++i)
assert(Operands[i]->isLoopInvariant(l) &&
"Operands of AddRec must be loop-invariant!");
@@ -404,7 +416,7 @@ namespace llvm {
/// of degree N, it returns a chrec of degree N-1.
SCEVHandle getStepRecurrence(ScalarEvolution &SE) const {
if (isAffine()) return getOperand(1);
- return SE.getAddRecExpr(std::vector<SCEVHandle>(op_begin()+1,op_end()),
+ return SE.getAddRecExpr(SmallVector<SCEVHandle, 3>(op_begin()+1,op_end()),
getLoop());
}
@@ -463,8 +475,9 @@ namespace llvm {
class SCEVSMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
- explicit SCEVSMaxExpr(const std::vector<SCEVHandle> &ops)
- : SCEVCommutativeExpr(scSMaxExpr, ops) {
+ explicit SCEVSMaxExpr(const SmallVectorImpl<SCEVHandle> &ops,
+ const ScalarEvolution* p)
+ : SCEVCommutativeExpr(scSMaxExpr, ops, p) {
}
public:
@@ -484,8 +497,9 @@ namespace llvm {
class SCEVUMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
- explicit SCEVUMaxExpr(const std::vector<SCEVHandle> &ops)
- : SCEVCommutativeExpr(scUMaxExpr, ops) {
+ explicit SCEVUMaxExpr(const SmallVectorImpl<SCEVHandle> &ops,
+ const ScalarEvolution* p)
+ : SCEVCommutativeExpr(scUMaxExpr, ops, p) {
}
public:
@@ -508,7 +522,8 @@ namespace llvm {
friend class ScalarEvolution;
Value *V;
- explicit SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {}
+ explicit SCEVUnknown(Value *v, const ScalarEvolution* p) :
+ SCEV(scUnknown, p), V(v) {}
protected:
~SCEVUnknown();
diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h
index 072f7c3863027..318ea287510e7 100644
--- a/include/llvm/CallingConv.h
+++ b/include/llvm/CallingConv.h
@@ -57,7 +57,18 @@ namespace CallingConv {
/// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
/// in ECX:EDX registers, others - via stack. Callee is responsible for
/// stack cleaning.
- X86_FastCall = 65
+ X86_FastCall = 65,
+
+ /// ARM_APCS - ARM Procedure Calling Standard calling convention (obsolete,
+ /// but still used on some targets).
+ ARM_APCS = 66,
+
+ /// ARM_AAPCS - ARM Architecture Procedure Calling Standard calling
+ /// convention (aka EABI). Soft float variant.
+ ARM_AAPCS = 67,
+
+ /// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI.
+ ARM_AAPCS_VFP = 68
};
} // End CallingConv namespace
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 38c1710d71032..c7b1a42d06b62 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -16,7 +16,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/CodeGen/DebugLoc.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
namespace llvm {
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index f1ae587ac1954..0cb7e90043873 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -29,29 +29,112 @@
namespace llvm {
class MachineInstr;
+ class MachineRegisterInfo;
class TargetRegisterInfo;
struct LiveInterval;
- /// VNInfo - If the value number definition is undefined (e.g. phi
- /// merge point), it contains ~0u,x. If the value number is not in use, it
- /// contains ~1u,x to indicate that the value # is not used.
- /// def - Instruction # of the definition.
- /// - or reg # of the definition if it's a stack slot liveinterval.
- /// copy - Copy iff val# is defined by a copy; zero otherwise.
- /// hasPHIKill - One or more of the kills are PHI nodes.
- /// redefByEC - Re-defined by early clobber somewhere during the live range.
- /// kills - Instruction # of the kills.
- struct VNInfo {
+ /// VNInfo - Value Number Information.
+ /// This class holds information about a machine level values, including
+ /// definition and use points.
+ ///
+ /// Care must be taken in interpreting the def index of the value. The
+ /// following rules apply:
+ ///
+ /// If the isDefAccurate() method returns false then def does not contain the
+ /// index of the defining MachineInstr, or even (necessarily) to a
+ /// MachineInstr at all. In general such a def index is not meaningful
+ /// and should not be used. The exception is that, for values originally
+ /// defined by PHI instructions, after PHI elimination def will contain the
+ /// index of the MBB in which the PHI originally existed. This can be used
+ /// to insert code (spills or copies) which deals with the value, which will
+ /// be live in to the block.
+
+ class VNInfo {
+ private:
+ enum {
+ HAS_PHI_KILL = 1,
+ REDEF_BY_EC = 1 << 1,
+ IS_PHI_DEF = 1 << 2,
+ IS_UNUSED = 1 << 3,
+ IS_DEF_ACCURATE = 1 << 4
+ };
+
+ unsigned char flags;
+
+ public:
+ /// The ID number of this value.
unsigned id;
+
+ /// The index of the defining instruction (if isDefAccurate() returns true).
unsigned def;
MachineInstr *copy;
- bool hasPHIKill : 1;
- bool redefByEC : 1;
SmallVector<unsigned, 4> kills;
+
VNInfo()
- : id(~1U), def(~1U), copy(0), hasPHIKill(false), redefByEC(false) {}
+ : flags(IS_UNUSED), id(~1U), def(0), copy(0) {}
+
+ /// VNInfo constructor.
+ /// d is presumed to point to the actual defining instr. If it doesn't
+ /// setIsDefAccurate(false) should be called after construction.
VNInfo(unsigned i, unsigned d, MachineInstr *c)
- : id(i), def(d), copy(c), hasPHIKill(false), redefByEC(false) {}
+ : flags(IS_DEF_ACCURATE), id(i), def(d), copy(c) {}
+
+ /// VNInfo construtor, copies values from orig, except for the value number.
+ VNInfo(unsigned i, const VNInfo &orig)
+ : flags(orig.flags), id(i), def(orig.def), copy(orig.copy),
+ kills(orig.kills) {}
+
+ /// Used for copying value number info.
+ unsigned getFlags() const { return flags; }
+ void setFlags(unsigned flags) { this->flags = flags; }
+
+ /// Returns true if one or more kills are PHI nodes.
+ bool hasPHIKill() const { return flags & HAS_PHI_KILL; }
+ void setHasPHIKill(bool hasKill) {
+ if (hasKill)
+ flags |= HAS_PHI_KILL;
+ else
+ flags &= ~HAS_PHI_KILL;
+ }
+
+ /// Returns true if this value is re-defined by an early clobber somewhere
+ /// during the live range.
+ bool hasRedefByEC() const { return flags & REDEF_BY_EC; }
+ void setHasRedefByEC(bool hasRedef) {
+ if (hasRedef)
+ flags |= REDEF_BY_EC;
+ else
+ flags &= ~REDEF_BY_EC;
+ }
+
+ /// Returns true if this value is defined by a PHI instruction (or was,
+ /// PHI instrucions may have been eliminated).
+ bool isPHIDef() const { return flags & IS_PHI_DEF; }
+ void setIsPHIDef(bool phiDef) {
+ if (phiDef)
+ flags |= IS_PHI_DEF;
+ else
+ flags &= ~IS_PHI_DEF;
+ }
+
+ /// Returns true if this value is unused.
+ bool isUnused() const { return flags & IS_UNUSED; }
+ void setIsUnused(bool unused) {
+ if (unused)
+ flags |= IS_UNUSED;
+ else
+ flags &= ~IS_UNUSED;
+ }
+
+ /// Returns true if the def is accurate.
+ bool isDefAccurate() const { return flags & IS_DEF_ACCURATE; }
+ void setIsDefAccurate(bool defAccurate) {
+ if (defAccurate)
+ flags |= IS_DEF_ACCURATE;
+ else
+ flags &= ~IS_DEF_ACCURATE;
+ }
+
};
/// LiveRange structure - This represents a simple register range in the
@@ -108,7 +191,6 @@ namespace llvm {
unsigned reg; // the register or stack slot of this interval
// if the top bits is set, it represents a stack slot.
float weight; // weight of this interval
- unsigned short preference; // preferred register for this interval
Ranges ranges; // the ranges in which this register is live
VNInfoList valnos; // value#'s
@@ -134,7 +216,7 @@ namespace llvm {
};
LiveInterval(unsigned Reg, float Weight, bool IsSS = false)
- : reg(Reg), weight(Weight), preference(0) {
+ : reg(Reg), weight(Weight) {
if (IsSS)
reg = reg | (1U << (sizeof(unsigned)*CHAR_BIT-1));
}
@@ -210,15 +292,17 @@ namespace llvm {
void copyValNumInfo(VNInfo *DstValNo, const VNInfo *SrcValNo) {
DstValNo->def = SrcValNo->def;
DstValNo->copy = SrcValNo->copy;
- DstValNo->hasPHIKill = SrcValNo->hasPHIKill;
- DstValNo->redefByEC = SrcValNo->redefByEC;
+ DstValNo->setFlags(SrcValNo->getFlags());
DstValNo->kills = SrcValNo->kills;
}
/// getNextValue - Create a new value number and return it. MIIdx specifies
/// the instruction that defines the value number.
VNInfo *getNextValue(unsigned MIIdx, MachineInstr *CopyMI,
- BumpPtrAllocator &VNInfoAllocator) {
+ bool isDefAccurate, BumpPtrAllocator &VNInfoAllocator) {
+
+ assert(MIIdx != ~0u && MIIdx != ~1u &&
+ "PHI def / unused flags should now be passed explicitly.");
#ifdef __GNUC__
unsigned Alignment = (unsigned)__alignof__(VNInfo);
#else
@@ -229,6 +313,26 @@ namespace llvm {
static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
Alignment));
new (VNI) VNInfo((unsigned)valnos.size(), MIIdx, CopyMI);
+ VNI->setIsDefAccurate(isDefAccurate);
+ valnos.push_back(VNI);
+ return VNI;
+ }
+
+ /// Create a copy of the given value. The new value will be identical except
+ /// for the Value number.
+ VNInfo *createValueCopy(const VNInfo *orig, BumpPtrAllocator &VNInfoAllocator) {
+
+#ifdef __GNUC__
+ unsigned Alignment = (unsigned)__alignof__(VNInfo);
+#else
+ // FIXME: ugly.
+ unsigned Alignment = 8;
+#endif
+ VNInfo *VNI =
+ static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
+ Alignment));
+
+ new (VNI) VNInfo((unsigned)valnos.size(), *orig);
valnos.push_back(VNI);
return VNI;
}
@@ -339,7 +443,8 @@ namespace llvm {
/// Copy - Copy the specified live interval. This copies all the fields
/// except for the register of the interval.
- void Copy(const LiveInterval &RHS, BumpPtrAllocator &VNInfoAllocator);
+ void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI,
+ BumpPtrAllocator &VNInfoAllocator);
bool empty() const { return ranges.empty(); }
@@ -416,7 +521,8 @@ namespace llvm {
/// the intervals are not joinable, this aborts.
void join(LiveInterval &Other, const int *ValNoAssignments,
const int *RHSValNoAssignments,
- SmallVector<VNInfo*, 16> &NewVNInfo);
+ SmallVector<VNInfo*, 16> &NewVNInfo,
+ MachineRegisterInfo *MRI);
/// isInOneLiveRange - Return true if the range specified is entirely in the
/// a single LiveRange of the live interval.
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index a110e5846ac90..0074f1a5f2cac 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -19,7 +19,7 @@
#define LLVM_CODEGEN_MACHINEFUNCTION_H
#include "llvm/ADT/ilist.h"
-#include "llvm/CodeGen/DebugLoc.h"
+#include "llvm/Support/DebugLoc.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Support/Annotation.h"
#include "llvm/Support/Allocator.h"
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index d61e5d8a5eb49..2b2f24a88371e 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/Target/TargetInstrDesc.h"
-#include "llvm/CodeGen/DebugLoc.h"
+#include "llvm/Support/DebugLoc.h"
#include <list>
#include <vector>
@@ -104,7 +104,7 @@ public:
/// getDebugLoc - Returns the debug location id of this MachineInstr.
///
- const DebugLoc getDebugLoc() const { return debugLoc; }
+ DebugLoc getDebugLoc() const { return debugLoc; }
/// getDesc - Returns the target instruction descriptor of this
/// MachineInstr.
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 7a4168447b62e..ba538d795ffd4 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -33,15 +33,15 @@ class raw_ostream;
class MachineOperand {
public:
enum MachineOperandType {
- MO_Register, ///< Register operand.
- MO_Immediate, ///< Immediate operand
- MO_FPImmediate, ///< Floating-point immediate operand
- MO_MachineBasicBlock, ///< MachineBasicBlock reference
- MO_FrameIndex, ///< Abstract Stack Frame Index
- MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
- MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
- MO_ExternalSymbol, ///< Name of external global symbol
- MO_GlobalAddress ///< Address of a global value
+ MO_Register, ///< Register operand.
+ MO_Immediate, ///< Immediate operand
+ MO_FPImmediate, ///< Floating-point immediate operand
+ MO_MachineBasicBlock, ///< MachineBasicBlock reference
+ MO_FrameIndex, ///< Abstract Stack Frame Index
+ MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
+ MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
+ MO_ExternalSymbol, ///< Name of external global symbol
+ MO_GlobalAddress ///< Address of a global value
};
private:
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 02f9b7c686e26..80c37b39ca0ca 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -37,6 +37,15 @@ class MachineRegisterInfo {
/// virtual registers. For each target register class, it keeps a list of
/// virtual registers belonging to the class.
std::vector<std::vector<unsigned> > RegClass2VRegMap;
+
+ /// RegAllocHints - This vector records register allocation hints for virtual
+ /// registers. For each virtual register, it keeps a register and hint type
+ /// pair making up the allocation hint. Hint type is target specific except
+ /// for the value 0 which means the second value of the pair is the preferred
+ /// register for allocation. For example, if the hint is <0, 1024>, it means
+ /// the allocator should prefer the physical register allocated to the virtual
+ /// register of the hint.
+ std::vector<std::pair<unsigned, unsigned> > RegAllocHints;
/// PhysRegUseDefLists - This is an array of the head of the use/def list for
/// physical registers.
@@ -170,7 +179,25 @@ public:
std::vector<unsigned> &getRegClassVirtRegs(const TargetRegisterClass *RC) {
return RegClass2VRegMap[RC->getID()];
}
-
+
+ /// setRegAllocationHint - Specify a register allocation hint for the
+ /// specified virtual register.
+ void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
+ Reg -= TargetRegisterInfo::FirstVirtualRegister;
+ assert(Reg < VRegInfo.size() && "Invalid vreg!");
+ RegAllocHints[Reg].first = Type;
+ RegAllocHints[Reg].second = PrefReg;
+ }
+
+ /// getRegAllocationHint - Return the register allocation hint for the
+ /// specified virtual register.
+ std::pair<unsigned, unsigned>
+ getRegAllocationHint(unsigned Reg) const {
+ Reg -= TargetRegisterInfo::FirstVirtualRegister;
+ assert(Reg < VRegInfo.size() && "Invalid vreg!");
+ return RegAllocHints[Reg];
+ }
+
//===--------------------------------------------------------------------===//
// Physical Register Use Info
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
index dd76fcc11b5e1..7f2c8bc368402 100644
--- a/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -153,6 +153,8 @@ namespace RTLIB {
FPROUND_PPCF128_F32,
FPROUND_F80_F64,
FPROUND_PPCF128_F64,
+ FPTOSINT_F32_I8,
+ FPTOSINT_F32_I16,
FPTOSINT_F32_I32,
FPTOSINT_F32_I64,
FPTOSINT_F32_I128,
@@ -165,6 +167,8 @@ namespace RTLIB {
FPTOSINT_PPCF128_I32,
FPTOSINT_PPCF128_I64,
FPTOSINT_PPCF128_I128,
+ FPTOUINT_F32_I8,
+ FPTOUINT_F32_I16,
FPTOUINT_F32_I32,
FPTOUINT_F32_I64,
FPTOUINT_F32_I128,
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index ad485103fb7ec..1b6fecd556e16 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -31,7 +31,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/RecyclingAllocator.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/CodeGen/DebugLoc.h"
+#include "llvm/Support/DebugLoc.h"
#include <cassert>
#include <climits>
diff --git a/include/llvm/Config/AsmPrinters.def.in b/include/llvm/Config/AsmPrinters.def.in
new file mode 100644
index 0000000000000..9729bd75eb40d
--- /dev/null
+++ b/include/llvm/Config/AsmPrinters.def.in
@@ -0,0 +1,29 @@
+//===- llvm/Config/AsmPrinters.def - LLVM Assembly Printers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language printers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PRINTER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly printers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASM_PRINTER
+# error Please define the macro LLVM_ASM_PRINTER(TargetName)
+#endif
+
+@LLVM_ENUM_ASM_PRINTERS@
+
+#undef LLVM_ASM_PRINTER
diff --git a/include/llvm/Config/Targets.def.in b/include/llvm/Config/Targets.def.in
new file mode 100644
index 0000000000000..a3884729e118d
--- /dev/null
+++ b/include/llvm/Config/Targets.def.in
@@ -0,0 +1,28 @@
+//===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the target architectures supported by
+// this build of LLVM. Clients of this file should define the
+// LLVM_TARGET macro to be a function-like macro with a single
+// parameter (the name of the target); including this file will then
+// enumerate all of the targets.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET
+# error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+@LLVM_ENUM_TARGETS@
+
+#undef LLVM_TARGET
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 33e2e002e231a..c59ed23d8b25f 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -580,3 +580,6 @@
/* Define to a function implementing strdup */
#cmakedefine strdup ${strdup}
+
+/* Native LLVM architecture */
+#cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index eee2f946148bd..ac60f4dc3a503 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -285,6 +285,9 @@
/* Have pthread_mutex_lock */
#undef HAVE_PTHREAD_MUTEX_LOCK
+/* Have pthread_rwlock_init */
+#undef HAVE_PTHREAD_RWLOCK_INIT
+
/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
#undef HAVE_RAND48
@@ -473,6 +476,9 @@
/* Build multithreading support into LLVM */
#undef LLVM_MULTITHREADED
+/* LLVM architecture name for the native architecture, if available */
+#undef LLVM_NATIVE_ARCH
+
/* Define if this is Unixish platform */
#undef LLVM_ON_UNIX
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index ed0fe2740f928..52fff2020c745 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -102,19 +102,28 @@ public:
return CreateTrueFalseVals(false);
}
- /// Return a ConstantInt with the specified value for the specified type. The
- /// value V will be canonicalized to an unsigned APInt. Accessing it with
- /// either getSExtValue() or getZExtValue() will yield a correctly sized and
- /// signed value for the type Ty.
+ /// Return a ConstantInt with the specified integer value for the specified
+ /// type. If the type is wider than 64 bits, the value will be zero-extended
+ /// to fit the type, unless isSigned is true, in which case the value will
+ /// be interpreted as a 64-bit signed integer and sign-extended to fit
+ /// the type.
/// @brief Get a ConstantInt for a specific value.
- static ConstantInt *get(const Type *Ty, uint64_t V, bool isSigned = false);
+ static ConstantInt *get(const IntegerType *Ty,
+ uint64_t V, bool isSigned = false);
+
+ /// If Ty is a vector type, return a Constant with a splat of the given
+ /// value. Otherwise return a ConstantInt for the given value.
+ static Constant *get(const Type *Ty, uint64_t V, bool isSigned = false);
/// Return a ConstantInt with the specified value for the specified type. The
/// value V will be canonicalized to a an unsigned APInt. Accessing it with
/// either getSExtValue() or getZExtValue() will yield a correctly sized and
/// signed value for the type Ty.
/// @brief Get a ConstantInt for a specific signed value.
- static ConstantInt *getSigned(const Type *Ty, int64_t V) {
+ static ConstantInt *getSigned(const IntegerType *Ty, int64_t V) {
+ return get(Ty, V, true);
+ }
+ static Constant *getSigned(const Type *Ty, int64_t V) {
return get(Ty, V, true);
}
@@ -122,6 +131,10 @@ public:
/// type is the integer type that corresponds to the bit width of the value.
static ConstantInt *get(const APInt &V);
+ /// If Ty is a vector type, return a Constant with a splat of the given
+ /// value. Otherwise return a ConstantInt for the given value.
+ static Constant *get(const Type *Ty, const APInt &V);
+
/// getType - Specialize the getType() method to always return an IntegerType,
/// which reduces the amount of casting needed in parts of the compiler.
///
@@ -248,10 +261,11 @@ public:
/// get() - Static factory methods - Return objects of the specified value
static ConstantFP *get(const APFloat &V);
- /// get() - This returns a constant fp for the specified value in the
- /// specified type. This should only be used for simple constant values like
- /// 2.0/1.0 etc, that are known-valid both as double and as the target format.
- static ConstantFP *get(const Type *Ty, double V);
+ /// get() - This returns a ConstantFP, or a vector containing a splat of a
+ /// ConstantFP, for the specified value in the specified type. This should
+ /// only be used for simple constant values like 2.0/1.0 etc, that are
+ /// known-valid both as host double and as the target format.
+ static Constant *get(const Type *Ty, double V);
/// isValueValidForType - return true if Ty is big enough to represent V.
static bool isValueValidForType(const Type *Ty, const APFloat& V);
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index fa951bf70d05e..b5824f8f81563 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -50,6 +50,10 @@ protected:
///
void dropAllTypeUses();
+ /// unlockedRefineAbstractTypeTo - Internal version of refineAbstractTypeTo
+ /// that performs no locking. Only used for internal recursion.
+ void unlockedRefineAbstractTypeTo(const Type *NewType);
+
public:
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
new file mode 100644
index 0000000000000..cadc23ab7109e
--- /dev/null
+++ b/include/llvm/MC/MCInst.h
@@ -0,0 +1,125 @@
+//===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCInst and MCOperand classes, which
+// is the basic representation used to represent low-level machine code
+// instructions.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_MC_MCINST_H
+#define LLVM_MC_MCINST_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/DebugLoc.h"
+
+namespace llvm {
+
+/// MCOperand - Instances of this class represent operands of the MCInst class.
+/// This is a simple discriminated union.
+class MCOperand {
+ enum MachineOperandType {
+ kInvalid, ///< Uninitialized.
+ kRegister, ///< Register operand.
+ kImmediate, ///< Immediate operand.
+ kMBBLabel ///< Basic block label.
+ };
+ unsigned char Kind;
+
+ union {
+ unsigned RegVal;
+ int64_t ImmVal;
+ struct {
+ unsigned FunctionNo;
+ unsigned BlockNo;
+ } MBBLabel;
+ };
+public:
+
+ MCOperand() : Kind(kInvalid) {}
+ MCOperand(const MCOperand &RHS) { *this = RHS; }
+
+ bool isReg() const { return Kind == kRegister; }
+ bool isImm() const { return Kind == kImmediate; }
+ bool isMBBLabel() const { return Kind == kMBBLabel; }
+
+ /// getReg - Returns the register number.
+ unsigned getReg() const {
+ assert(isReg() && "This is not a register operand!");
+ return RegVal;
+ }
+
+ /// setReg - Set the register number.
+ void setReg(unsigned Reg) {
+ assert(isReg() && "This is not a register operand!");
+ RegVal = Reg;
+ }
+
+ int64_t getImm() const {
+ assert(isImm() && "This is not an immediate");
+ return ImmVal;
+ }
+ void setImm(int64_t Val) {
+ assert(isImm() && "This is not an immediate");
+ ImmVal = Val;
+ }
+
+ unsigned getMBBLabelFunction() const {
+ assert(isMBBLabel() && "Wrong accessor");
+ return MBBLabel.FunctionNo;
+ }
+ unsigned getMBBLabelBlock() const {
+ assert(isMBBLabel() && "Wrong accessor");
+ return MBBLabel.BlockNo;
+ }
+
+ void MakeReg(unsigned Reg) {
+ Kind = kRegister;
+ RegVal = Reg;
+ }
+ void MakeImm(int64_t Val) {
+ Kind = kImmediate;
+ ImmVal = Val;
+ }
+ void MakeMBBLabel(unsigned Fn, unsigned MBB) {
+ Kind = kMBBLabel;
+ MBBLabel.FunctionNo = Fn;
+ MBBLabel.BlockNo = MBB;
+ }
+};
+
+
+/// MCInst - Instances of this class represent a single low-level machine
+/// instruction.
+class MCInst {
+ unsigned Opcode;
+ SmallVector<MCOperand, 8> Operands;
+public:
+ MCInst() : Opcode(~0U) {}
+
+ void setOpcode(unsigned Op) { Opcode = Op; }
+
+ unsigned getOpcode() const { return Opcode; }
+ DebugLoc getDebugLoc() const { return DebugLoc(); }
+
+ const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
+ MCOperand &getOperand(unsigned i) { return Operands[i]; }
+
+ void addOperand(const MCOperand &Op) {
+ Operands.push_back(Op);
+ }
+
+};
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index fa3b8701d3494..3ae50136e4a9d 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -539,7 +539,7 @@ template<>
class parser<bool> : public basic_parser<bool> {
const char *ArgStr;
public:
-
+
// parse - Return true on error.
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
@@ -1105,7 +1105,7 @@ public:
}
};
-// multi_arg - Modifier to set the number of additional values.
+// multi_val - Modifier to set the number of additional values.
struct multi_val {
unsigned AdditionalVals;
explicit multi_val(unsigned N) : AdditionalVals(N) {}
diff --git a/include/llvm/CodeGen/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index 77e6733f696af..5c089efc98ce9 100644
--- a/include/llvm/CodeGen/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -1,4 +1,4 @@
-//===---- llvm/CodeGen/DebugLoc.h - Debug Location Information --*- C++ -*-===//
+//===---- llvm/DebugLoc.h - Debug Location Information ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines a number of light weight data structures used by the code
-// generator to describe and track debug location information.
+// This file defines a number of light weight data structures used
+// to describe and track debug location information.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_DEBUGLOC_H
-#define LLVM_CODEGEN_DEBUGLOC_H
+#ifndef LLVM_DEBUGLOC_H
+#define LLVM_DEBUGLOC_H
#include "llvm/ADT/DenseMap.h"
#include <vector>
@@ -98,4 +98,4 @@ namespace llvm {
} // end namespace llvm
-#endif /* LLVM_CODEGEN_DEBUGLOC_H */
+#endif /* LLVM_DEBUGLOC_H */
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index 7942de7857a2f..ed6a3f19ef7ab 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -17,6 +17,7 @@
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
+#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
#include "llvm/Support/ConstantFolder.h"
@@ -202,7 +203,7 @@ public:
Value *CreateFMul(Value *LHS, Value *RHS, const char *Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
- return Folder.CreateMul(LC, RC);
+ return Folder.CreateFMul(LC, RC);
return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name);
}
Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
@@ -291,6 +292,11 @@ public:
return Folder.CreateNeg(VC);
return Insert(BinaryOperator::CreateNeg(V), Name);
}
+ Value *CreateFNeg(Value *V, const char *Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Folder.CreateFNeg(VC);
+ return Insert(BinaryOperator::CreateFNeg(V), Name);
+ }
Value *CreateNot(Value *V, const char *Name = "") {
if (Constant *VC = dyn_cast<Constant>(V))
return Folder.CreateNot(VC);
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 619cc2055250a..4fc648319ad47 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -15,6 +15,7 @@
#define LLVM_SUPPORT_MANAGED_STATIC_H
#include "llvm/System/Atomic.h"
+#include "llvm/System/Threading.h"
namespace llvm {
@@ -60,28 +61,28 @@ public:
// Accessors.
C &operator*() {
void* tmp = Ptr;
- sys::MemoryFence();
+ if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
return *static_cast<C*>(Ptr);
}
C *operator->() {
void* tmp = Ptr;
- sys::MemoryFence();
+ if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
return static_cast<C*>(Ptr);
}
const C &operator*() const {
void* tmp = Ptr;
- sys::MemoryFence();
+ if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
return *static_cast<C*>(Ptr);
}
const C *operator->() const {
void* tmp = Ptr;
- sys::MemoryFence();
+ if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
return static_cast<C*>(Ptr);
@@ -94,13 +95,6 @@ public:
void Register() { RegisterManagedStatic(0, CleanupFn); }
};
-
-/// llvm_start_multithreaded - Allocate and initialize structures needed to
-/// make LLVM safe for multithreading. The return value indicates whether
-/// multithreaded initialization succeeded. LLVM will still be operational
-/// on "failed" return, but will not be safe to run multithreaded.
-bool llvm_start_multithreaded();
-
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
void llvm_shutdown();
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
new file mode 100644
index 0000000000000..25775cb74419d
--- /dev/null
+++ b/include/llvm/Support/SourceMgr.h
@@ -0,0 +1,120 @@
+//===- SourceMgr.h - Manager for Source Buffers & Diagnostics ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SourceMgr class. This class is used as a simple
+// substrate for diagnostics, #include handling, and other low level things for
+// simple parsers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_SOURCEMGR_H
+#define SUPPORT_SOURCEMGR_H
+
+#include <string>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ class MemoryBuffer;
+ class SourceMgr;
+
+class SMLoc {
+ const char *Ptr;
+public:
+ SMLoc() : Ptr(0) {}
+ SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {}
+
+ bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
+ bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
+
+ const char *getPointer() const { return Ptr; }
+
+ static SMLoc getFromPointer(const char *Ptr) {
+ SMLoc L;
+ L.Ptr = Ptr;
+ return L;
+ }
+};
+
+/// SourceMgr - This owns the files read by tblgen, handles include stacks,
+/// and handles printing of diagnostics.
+class SourceMgr {
+ struct SrcBuffer {
+ /// Buffer - The memory buffer for the file.
+ MemoryBuffer *Buffer;
+
+ /// IncludeLoc - This is the location of the parent include, or null if at
+ /// the top level.
+ SMLoc IncludeLoc;
+ };
+
+ /// Buffers - This is all of the buffers that we are reading from.
+ std::vector<SrcBuffer> Buffers;
+
+ // IncludeDirectories - This is the list of directories we should search for
+ // include files in.
+ std::vector<std::string> IncludeDirectories;
+
+ SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT
+ void operator=(const SourceMgr&); // DO NOT IMPLEMENT
+public:
+ SourceMgr() {}
+ ~SourceMgr();
+
+ void setIncludeDirs(const std::vector<std::string> &Dirs) {
+ IncludeDirectories = Dirs;
+ }
+
+ const SrcBuffer &getBufferInfo(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i];
+ }
+
+ const MemoryBuffer *getMemoryBuffer(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i].Buffer;
+ }
+
+ SMLoc getParentIncludeLoc(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i].IncludeLoc;
+ }
+
+ unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
+ SrcBuffer NB;
+ NB.Buffer = F;
+ NB.IncludeLoc = IncludeLoc;
+ Buffers.push_back(NB);
+ return Buffers.size()-1;
+ }
+
+ /// AddIncludeFile - Search for a file with the specified name in the current
+ /// directory or in one of the IncludeDirs. If no file is found, this returns
+ /// ~0, otherwise it returns the buffer ID of the stacked file.
+ unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc);
+
+ /// FindBufferContainingLoc - Return the ID of the buffer containing the
+ /// specified location, returning -1 if not found.
+ int FindBufferContainingLoc(SMLoc Loc) const;
+
+ /// FindLineNumber - Find the line number for the specified location in the
+ /// specified file. This is not a fast method.
+ unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const;
+
+ /// PrintMessage - Emit a message about the specified location with the
+ /// specified string.
+ void PrintMessage(SMLoc Loc, const std::string &Msg) const;
+
+private:
+ void PrintIncludeStack(SMLoc IncludeLoc) const;
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/System/Atomic.h b/include/llvm/System/Atomic.h
index cb9277cc35ec8..adbb975298e81 100644
--- a/include/llvm/System/Atomic.h
+++ b/include/llvm/System/Atomic.h
@@ -24,6 +24,8 @@ namespace llvm {
cas_flag CompareAndSwap(volatile cas_flag* ptr,
cas_flag new_value,
cas_flag old_value);
+ cas_flag AtomicIncrement(volatile cas_flag* ptr);
+ cas_flag AtomicDecrement(volatile cas_flag* ptr);
}
}
diff --git a/include/llvm/System/Mutex.h b/include/llvm/System/Mutex.h
index 4f3849341aa1f..d2c457dbc91c6 100644
--- a/include/llvm/System/Mutex.h
+++ b/include/llvm/System/Mutex.h
@@ -14,12 +14,15 @@
#ifndef LLVM_SYSTEM_MUTEX_H
#define LLVM_SYSTEM_MUTEX_H
+#include "llvm/System/Threading.h"
+#include <cassert>
+
namespace llvm
{
namespace sys
{
/// @brief Platform agnostic Mutex class.
- class Mutex
+ class MutexImpl
{
/// @name Constructors
/// @{
@@ -30,11 +33,11 @@ namespace llvm
/// also more likely to deadlock (same thread can't acquire more than
/// once).
/// @brief Default Constructor.
- explicit Mutex(bool recursive = true);
+ explicit MutexImpl(bool recursive = true);
/// Releases and removes the lock
/// @brief Destructor
- ~Mutex();
+ ~MutexImpl();
/// @}
/// @name Methods
@@ -66,18 +69,81 @@ namespace llvm
/// @name Platform Dependent Data
/// @{
private:
-#ifdef ENABLE_THREADS
void* data_; ///< We don't know what the data will be
-#endif
/// @}
/// @name Do Not Implement
/// @{
private:
- Mutex(const Mutex & original);
- void operator=(const Mutex &);
+ MutexImpl(const MutexImpl & original);
+ void operator=(const MutexImpl &);
/// @}
};
+
+
+ /// SmartMutex - A mutex with a compile time constant parameter that
+ /// indicates whether this mutex should become a no-op when we're not
+ /// running in multithreaded mode.
+ template<bool mt_only>
+ class SmartMutex : public MutexImpl {
+ unsigned acquired;
+ bool recursive;
+ public:
+ explicit SmartMutex(bool rec = true) :
+ MutexImpl(rec), acquired(0), recursive(rec) { }
+
+ bool acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return MutexImpl::acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert((recursive || acquired == 0) && "Lock already acquired!!");
+ ++acquired;
+ return true;
+ }
+
+ bool release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return MutexImpl::release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(((recursive && acquired) || (acquired == 1)) &&
+ "Lock not acquired before release!");
+ --acquired;
+ return true;
+ }
+
+ bool tryacquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return MutexImpl::tryacquire();
+ return true;
+ }
+
+ private:
+ SmartMutex(const SmartMutex<mt_only> & original);
+ void operator=(const SmartMutex<mt_only> &);
+ };
+
+ /// Mutex - A standard, always enforced mutex.
+ typedef SmartMutex<false> Mutex;
+
+ template<bool mt_only>
+ class SmartScopedLock {
+ SmartMutex<mt_only>* mtx;
+
+ public:
+ SmartScopedLock(SmartMutex<mt_only>* m) : mtx(m) {
+ mtx->acquire();
+ }
+
+ ~SmartScopedLock() {
+ mtx->release();
+ }
+ };
+
+ typedef SmartScopedLock<false> ScopedLock;
}
}
diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h
index de2f173ae4175..05be2212758b4 100644
--- a/include/llvm/System/Path.h
+++ b/include/llvm/System/Path.h
@@ -309,6 +309,11 @@ namespace sys {
/// @brief Determine if the path is absolute.
bool isAbsolute() const;
+ /// This function determines if the path name is absolute, as opposed to
+ /// relative.
+ /// @brief Determine if the path is absolute.
+ static bool isAbsolute(const char *NameStart, unsigned NameLen);
+
/// This function opens the file associated with the path name provided by
/// the Path object and reads its magic number. If the magic number at the
/// start of the file matches \p magic, true is returned. In all other
diff --git a/include/llvm/System/RWMutex.h b/include/llvm/System/RWMutex.h
new file mode 100644
index 0000000000000..e577d457afb51
--- /dev/null
+++ b/include/llvm/System/RWMutex.h
@@ -0,0 +1,175 @@
+//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_RWMUTEX_H
+#define LLVM_SYSTEM_RWMUTEX_H
+
+#include "llvm/System/Threading.h"
+#include <cassert>
+
+namespace llvm
+{
+ namespace sys
+ {
+ /// @brief Platform agnostic RWMutex class.
+ class RWMutexImpl
+ {
+ /// @name Constructors
+ /// @{
+ public:
+
+ /// Initializes the lock but doesn't acquire it.
+ /// @brief Default Constructor.
+ explicit RWMutexImpl();
+
+ /// Releases and removes the lock
+ /// @brief Destructor
+ ~RWMutexImpl();
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+
+ /// Attempts to unconditionally acquire the lock in reader mode. If the
+ /// lock is held by a writer, this method will wait until it can acquire
+ /// the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock in reader mode.
+ bool reader_acquire();
+
+ /// Attempts to release the lock in reader mode.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock in reader mode.
+ bool reader_release();
+
+ /// Attempts to unconditionally acquire the lock in reader mode. If the
+ /// lock is held by any readers, this method will wait until it can
+ /// acquire the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock in writer mode.
+ bool writer_acquire();
+
+ /// Attempts to release the lock in writer mode.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock in write mode.
+ bool writer_release();
+
+ //@}
+ /// @name Platform Dependent Data
+ /// @{
+ private:
+ void* data_; ///< We don't know what the data will be
+
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ private:
+ RWMutexImpl(const RWMutexImpl & original);
+ void operator=(const RWMutexImpl &);
+ /// @}
+ };
+
+ /// SmartMutex - An R/W mutex with a compile time constant parameter that
+ /// indicates whether this mutex should become a no-op when we're not
+ /// running in multithreaded mode.
+ template<bool mt_only>
+ class SmartRWMutex : public RWMutexImpl {
+ unsigned readers, writers;
+ public:
+ explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
+
+ bool reader_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ ++readers;
+ return true;
+ }
+
+ bool reader_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(readers > 0 && "Reader lock not acquired before release!");
+ --readers;
+ return true;
+ }
+
+ bool writer_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 0 && "Writer lock already acquired!");
+ ++writers;
+ return true;
+ }
+
+ bool writer_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 1 && "Writer lock not acquired before release!");
+ --writers;
+ return true;
+ }
+
+ private:
+ SmartRWMutex(const SmartRWMutex<mt_only> & original);
+ void operator=(const SmartRWMutex<mt_only> &);
+ };
+ typedef SmartRWMutex<false> RWMutex;
+
+ /// ScopedReader - RAII acquisition of a reader lock
+ template<bool mt_only>
+ struct SmartScopedReader {
+ SmartRWMutex<mt_only>* mutex;
+
+ explicit SmartScopedReader(SmartRWMutex<mt_only>* m) {
+ mutex = m;
+ mutex->reader_acquire();
+ }
+
+ ~SmartScopedReader() {
+ mutex->reader_release();
+ }
+ };
+ typedef SmartScopedReader<false> ScopedReader;
+
+ /// ScopedWriter - RAII acquisition of a writer lock
+ template<bool mt_only>
+ struct SmartScopedWriter {
+ SmartRWMutex<mt_only>* mutex;
+
+ explicit SmartScopedWriter(SmartRWMutex<mt_only>* m) {
+ mutex = m;
+ mutex->writer_acquire();
+ }
+
+ ~SmartScopedWriter() {
+ mutex->writer_release();
+ }
+ };
+ typedef SmartScopedWriter<false> ScopedWriter;
+ }
+}
+
+#endif
diff --git a/include/llvm/System/Threading.h b/include/llvm/System/Threading.h
new file mode 100644
index 0000000000000..42d2f89bcb825
--- /dev/null
+++ b/include/llvm/System/Threading.h
@@ -0,0 +1,45 @@
+//===-- llvm/System/Threading.h - Control multithreading mode --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// TThis file defines llvm_start_multithreaded() and friends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_THREADING_H
+#define LLVM_SYSTEM_THREADING_H
+
+namespace llvm {
+ /// llvm_start_multithreaded - Allocate and initialize structures needed to
+ /// make LLVM safe for multithreading. The return value indicates whether
+ /// multithreaded initialization succeeded. LLVM will still be operational
+ /// on "failed" return, and will still be safe for hosting threading
+ /// applications in the JIT, but will not be safe for concurrent calls to the
+ /// LLVM APIs.
+ /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
+ bool llvm_start_multithreaded();
+
+ /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
+ /// safe for multithreading.
+ /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
+ void llvm_stop_multithreaded();
+
+ /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
+ /// mode or not.
+ bool llvm_is_multithreaded();
+
+ /// acquire_global_lock - Acquire the global lock. This is a no-op if called
+ /// before llvm_start_multithreaded().
+ void llvm_acquire_global_lock();
+
+ /// release_global_lock - Release the global lock. This is a no-op if called
+ /// before llvm_start_multithreaded().
+ void llvm_release_global_lock();
+}
+
+#endif
diff --git a/include/llvm/Target/DarwinTargetAsmInfo.h b/include/llvm/Target/DarwinTargetAsmInfo.h
index 6241ffe29b8f2..171a6b3e1177d 100644
--- a/include/llvm/Target/DarwinTargetAsmInfo.h
+++ b/include/llvm/Target/DarwinTargetAsmInfo.h
@@ -23,7 +23,7 @@ namespace llvm {
class Type;
class Mangler;
- struct DarwinTargetAsmInfo: public TargetAsmInfo {
+ struct DarwinTargetAsmInfo : public TargetAsmInfo {
const Section* TextCoalSection;
const Section* ConstTextCoalSection;
const Section* ConstDataCoalSection;
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 3f1cdd27ca394..ebd826a6f4a16 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -274,6 +274,7 @@ def unknown;
class Operand<ValueType ty> {
ValueType Type = ty;
string PrintMethod = "printOperand";
+ string AsmOperandLowerMethod = ?;
dag MIOperandInfo = (ops);
}
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index f223f4765f988..670b0996cc350 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -130,7 +130,6 @@ namespace llvm {
private:
mutable StringMap<Section> Sections;
mutable SectionFlags::FlagsStringsMapType FlagsStrings;
- void fillDefaultValues();
protected:
/// TM - The current TargetMachine.
const TargetMachine &TM;
@@ -278,6 +277,10 @@ namespace llvm {
/// use '\1' as the first character.
const char *StringConstantPrefix; // Defaults to ".str"
+ /// AllowQuotesInName - This is true if the assembler allows for complex
+ /// symbol names to be surrounded in quotes. This defaults to false.
+ bool AllowQuotesInName;
+
//===--- Data Emission Directives -------------------------------------===//
/// ZeroDirective - this should be set to the directive used to get some
@@ -308,8 +311,7 @@ namespace llvm {
/// directives for various sizes and non-default address spaces.
virtual const char *getASDirective(unsigned size,
unsigned AS) const {
- assert (AS > 0
- && "Dont know the directives for default addr space");
+ assert(AS > 0 && "Dont know the directives for default addr space");
return NULL;
}
@@ -472,10 +474,6 @@ namespace llvm {
/// encode inline subroutine information.
bool DwarfUsesInlineInfoSection; // Defaults to false.
- /// SupportsMacInfo - true if the Dwarf output supports macro information
- ///
- bool SupportsMacInfoSection; // Defaults to true
-
/// NonLocalEHFrameLabel - If set, the EH_frame label needs to be non-local.
///
bool NonLocalEHFrameLabel; // Defaults to false.
@@ -536,9 +534,9 @@ namespace llvm {
///
const char *DwarfRangesSection; // Defaults to ".debug_ranges".
- /// DwarfMacInfoSection - Section directive for Dwarf info.
+ /// DwarfMacroInfoSection - Section directive for DWARF macro info.
///
- const char *DwarfMacInfoSection; // Defaults to ".debug_macinfo".
+ const char *DwarfMacroInfoSection; // Defaults to ".debug_macinfo".
/// DwarfEHFrameSection - Section directive for Exception frames.
///
@@ -749,6 +747,9 @@ namespace llvm {
const char *getStringConstantPrefix() const {
return StringConstantPrefix;
}
+ bool doesAllowQuotesInName() const {
+ return AllowQuotesInName;
+ }
const char *getZeroDirective() const {
return ZeroDirective;
}
@@ -866,9 +867,6 @@ namespace llvm {
bool doesDwarfUsesInlineInfoSection() const {
return DwarfUsesInlineInfoSection;
}
- bool doesSupportMacInfoSection() const {
- return SupportsMacInfoSection;
- }
bool doesRequireNonLocalEHFrameLabel() const {
return NonLocalEHFrameLabel;
}
@@ -914,8 +912,8 @@ namespace llvm {
const char *getDwarfRangesSection() const {
return DwarfRangesSection;
}
- const char *getDwarfMacInfoSection() const {
- return DwarfMacInfoSection;
+ const char *getDwarfMacroInfoSection() const {
+ return DwarfMacroInfoSection;
}
const char *getDwarfEHFrameSection() const {
return DwarfEHFrameSection;
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 47dcc6c8e48f3..40b0e7be480b4 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -30,7 +30,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/CodeGen/DebugLoc.h"
+#include "llvm/Support/DebugLoc.h"
#include "llvm/Target/TargetMachine.h"
#include <climits>
#include <map>
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index a8db68c597892..33fc45161a6ea 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -78,11 +78,13 @@ namespace CodeGenOpt {
};
}
+
+// Possible float ABI settings. Used with FloatABIType in TargetOptions.h.
namespace FloatABI {
enum ABIType {
- Default,
- Soft,
- Hard
+ Default, // Target-specific (either soft of hard depending on triple, etc).
+ Soft, // Soft float.
+ Hard // Hard float.
};
}
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 0218bfdb2ae39..91e8f80fd108d 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -519,6 +519,36 @@ public:
return NULL;
}
+ /// getAllocationOrder - Returns the register allocation order for a specified
+ /// register class in the form of a pair of TargetRegisterClass iterators.
+ virtual std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
+ getAllocationOrder(const TargetRegisterClass *RC,
+ unsigned HintType, unsigned HintReg,
+ const MachineFunction &MF) const {
+ return std::make_pair(RC->allocation_order_begin(MF),
+ RC->allocation_order_end(MF));
+ }
+
+ /// ResolveRegAllocHint - Resolves the specified register allocation hint
+ /// to a physical register. Returns the physical register if it is successful.
+ virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
+ const MachineFunction &MF) const {
+ if (Type == 0 && Reg && isPhysicalRegister(Reg))
+ return Reg;
+ return 0;
+ }
+
+ /// UpdateRegAllocHint - A callback to allow target a chance to update
+ /// register allocation hints when a register is "changed" (e.g. coalesced)
+ /// to another register. e.g. On ARM, some virtual registers should target
+ /// register pairs, if one of pair is coalesced to another register, the
+ /// allocation hint of the other half of the pair should be changed to point
+ /// to the new register.
+ virtual void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
+ MachineFunction &MF) const {
+ // Do nothing.
+ }
+
/// targetHandlesStackFrameRounding - Returns true if the target is
/// responsible for rounding up the stack frame (probably at emitPrologue
/// time).
diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Target/TargetSelect.h
new file mode 100644
index 0000000000000..8544eed76be7e
--- /dev/null
+++ b/include/llvm/Target/TargetSelect.h
@@ -0,0 +1,65 @@
+//===- TargetSelect.h - Target Selection & Registration -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides utilities to make sure that certain classes of targets are
+// linked into the main application executable, and initialize them as
+// appropriate.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSELECT_H
+#define LLVM_TARGET_TARGETSELECT_H
+
+#include "llvm/Config/config.h"
+
+namespace llvm {
+ // Declare all of the target-initialization functions that are available.
+#define LLVM_TARGET(TargetName) void Initialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+
+ // Declare all of the available asm-printer initialization functions.
+ // Declare all of the target-initialization functions.
+#define LLVM_ASM_PRINTER(TargetName) void Initialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+
+ /// InitializeAllTargets - The main program should call this function if it
+ /// wants to link in all available targets that LLVM is configured to support.
+ inline void InitializeAllTargets() {
+#define LLVM_TARGET(TargetName) llvm::Initialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+ }
+
+ /// InitializeAllAsmPrinters - The main program should call this function if
+ /// it wants all asm printers that LLVM is configured to support. This will
+ /// cause them to be linked into its executable.
+ inline void InitializeAllAsmPrinters() {
+#define LLVM_ASM_PRINTER(TargetName) Initialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+ }
+
+
+ /// InitializeNativeTarget - The main program should call this function to
+ /// initialize the native target corresponding to the host. This is useful
+ /// for JIT applications to ensure that the target gets linked in correctly.
+ inline bool InitializeNativeTarget() {
+ // If we have a native target, initialize it to ensure it is linked in.
+#ifdef LLVM_NATIVE_ARCH
+#define DoInit2(TARG, MOD) llvm::Initialize ## TARG ## MOD()
+#define DoInit(T, M) DoInit2(T, M)
+ DoInit(LLVM_NATIVE_ARCH, Target);
+ return false;
+#undef DoInit
+#undef DoInit2
+#else
+ return true;
+#endif
+ }
+}
+
+#endif
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 2c3fdd4a78848..971baeef91001 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -143,10 +143,10 @@ Pass *createLoopIndexSplitPass();
// this pass is:
//
// FROM CODE TO CODE
-// %X = alloca int, uint 1 ret int 42
-// store int 42, int *%X
-// %Y = load int* %X
-// ret int %Y
+// %X = alloca i32, i32 1 ret i32 42
+// store i32 42, i32 *%X
+// %Y = load i32* %X
+// ret i32 %Y
//
FunctionPass *createPromoteMemoryToRegisterPass();
extern const PassInfo *const PromoteMemoryToRegisterID;
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 5ea1a500c59e1..7ab8721af76c9 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -31,6 +31,16 @@ struct DbgInfoIntrinsic;
template<typename T> class SmallVectorImpl;
//===----------------------------------------------------------------------===//
+// Local analysis.
+//
+
+/// isSafeToLoadUnconditionally - Return true if we know that executing a load
+/// from this value cannot trap. If it is not obviously safe to load from the
+/// specified pointer, we do a quick local scan of the basic block containing
+/// ScanFrom, to determine if the address is already accessed.
+bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom);
+
+//===----------------------------------------------------------------------===//
// Local constant propagation.
//
diff --git a/include/llvm/Type.h b/include/llvm/Type.h
index c1732af09bdd4..d439233d8c05d 100644
--- a/include/llvm/Type.h
+++ b/include/llvm/Type.h
@@ -14,6 +14,7 @@
#include "llvm/AbstractTypeUser.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/System/Atomic.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator.h"
#include <string>
@@ -102,7 +103,7 @@ private:
/// has no AbstractTypeUsers, the type is deleted. This is only sensical for
/// derived types.
///
- mutable unsigned RefCount;
+ mutable sys::cas_flag RefCount;
const Type *getForwardedTypeInternal() const;
@@ -268,19 +269,16 @@ public:
/// primitive type.
///
unsigned getPrimitiveSizeInBits() const;
-
+
+ /// getScalarSizeInBits - If this is a vector type, return the
+ /// getPrimitiveSizeInBits value for the element type. Otherwise return the
+ /// getPrimitiveSizeInBits value for this type.
+ unsigned getScalarSizeInBits() const;
+
/// getFPMantissaWidth - Return the width of the mantissa of this type. This
- /// is only valid on scalar floating point types. If the FP type does not
+ /// is only valid on floating point types. If the FP type does not
/// have a stable mantissa (e.g. ppc long double), this method returns -1.
- int getFPMantissaWidth() const {
- assert(isFloatingPoint() && "Not a floating point type!");
- if (ID == FloatTyID) return 24;
- if (ID == DoubleTyID) return 53;
- if (ID == X86_FP80TyID) return 64;
- if (ID == FP128TyID) return 113;
- assert(ID == PPC_FP128TyID && "unknown fp type");
- return -1;
- }
+ int getFPMantissaWidth() const;
/// getForwardedType - Return the type that this type has been resolved to if
/// it has been resolved to anything. This is used to implement the
@@ -296,6 +294,10 @@ public:
/// function.
const Type *getVAArgsPromotedType() const;
+ /// getScalarType - If this is a vector type, return the element type,
+ /// otherwise return this.
+ const Type *getScalarType() const;
+
//===--------------------------------------------------------------------===//
// Type Iteration support
//
@@ -336,7 +338,7 @@ public:
void addRef() const {
assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
- ++RefCount;
+ sys::AtomicIncrement(&RefCount);
}
void dropRef() const {
@@ -345,17 +347,15 @@ public:
// If this is the last PATypeHolder using this object, and there are no
// PATypeHandles using it, the type is dead, delete it now.
- if (--RefCount == 0 && AbstractTypeUsers.empty())
+ sys::cas_flag OldCount = sys::AtomicDecrement(&RefCount);
+ if (OldCount == 0 && AbstractTypeUsers.empty())
this->destroy();
}
/// addAbstractTypeUser - Notify an abstract type that there is a new user of
/// it. This function is called primarily by the PATypeHandle class.
///
- void addAbstractTypeUser(AbstractTypeUser *U) const {
- assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
- AbstractTypeUsers.push_back(U);
- }
+ void addAbstractTypeUser(AbstractTypeUser *U) const;
/// removeAbstractTypeUser - Notify an abstract type that a user of the class
/// no longer has a handle to the type. This function is called primarily by