diff options
Diffstat (limited to 'include/llvm')
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 |