diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2006-11-27 01:05:10 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2006-11-27 01:05:10 +0000 |
commit | 3da59db637a887474c1b1346c1f3ccf53b6c4663 (patch) | |
tree | b061e2133efdb9ea9bb334c1b15ceea881bb88f8 | |
parent | 5fed9b90447a9a95a1f670ccd9c23aea8c937451 (diff) |
For PR950:
The long awaited CAST patch. This introduces 12 new instructions into LLVM
to replace the cast instruction. Corresponding changes throughout LLVM are
provided. This passes llvm-test, llvm/test, and SPEC CPUINT2000 with the
exception of 175.vpr which fails only on a slight floating point output
difference.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31931 91177308-0d34-0410-b5e6-96231b3b80d8
105 files changed, 6683 insertions, 3646 deletions
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 391c12b2ba..163d35761c 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -27,7 +27,7 @@ namespace llvm { /// rewrite expressions in canonical form. /// /// Clients should create an instance of this class when rewriting is needed, - /// and destroying it when finished to allow the release of the associated + /// and destroy it when finished to allow the release of the associated /// memory. struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { ScalarEvolution &SE; @@ -115,12 +115,12 @@ namespace llvm { Value *visitTruncateExpr(SCEVTruncateExpr *S) { Value *V = expand(S->getOperand()); - return new CastInst(V, S->getType(), "tmp.", InsertPt); + return CastInst::createInferredCast(V, S->getType(), "tmp.", InsertPt); } Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S) { Value *V = expandInTy(S->getOperand(),S->getType()->getUnsignedVersion()); - return new CastInst(V, S->getType(), "tmp.", InsertPt); + return CastInst::createInferredCast(V, S->getType(), "tmp.", InsertPt); } Value *visitAddExpr(SCEVAddExpr *S) { diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 20f36438b1..f78ace36f8 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -516,9 +516,33 @@ public: /// Cast constant expr /// + static Constant *getTrunc (Constant *C, const Type *Ty); + static Constant *getSignExtend (Constant *C, const Type *Ty); + static Constant *getZeroExtend (Constant *C, const Type *Ty); + static Constant *getFPTrunc (Constant *C, const Type *Ty); + static Constant *getFPExtend (Constant *C, const Type *Ty); + static Constant *getUIToFP (Constant *C, const Type *Ty); + static Constant *getSIToFP (Constant *C, const Type *Ty); + static Constant *getFPToUI (Constant *C, const Type *Ty); + static Constant *getFPToSI (Constant *C, const Type *Ty); + static Constant *getPtrToInt (Constant *C, const Type *Ty); + static Constant *getIntToPtr (Constant *C, const Type *Ty); + static Constant *getBitCast (Constant *C, const Type *Ty); + + // @brief Convenience function for getting one of the casting operations + // using a CastOps opcode. + static Constant *getCast( + unsigned ops, ///< The opcode for the conversion + Constant *C, ///< The constant to be converted + const Type *Ty ///< The type to which the constant is converted + ); + + // @brief Get a ConstantExpr Conversion operator that casts C to Ty static Constant *getCast(Constant *C, const Type *Ty); - static Constant *getSignExtend(Constant *C, const Type *Ty); - static Constant *getZeroExtend(Constant *C, const Type *Ty); + + /// @brief Return true if this is a convert constant expression + bool isCast() const; + /// Select constant expr /// diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 627aad4304..0a489f3d08 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -244,6 +244,161 @@ public: }; //===----------------------------------------------------------------------===// +// CastInst Class +//===----------------------------------------------------------------------===// + +/// CastInst - This is the base class for all instructions that perform data +/// casts. It is simply provided so that instruction category testing +/// can be performed with code like: +/// +/// if (isa<CastInst>(Instr)) { ... } +/// @brief Base class of casting instructions. +class CastInst : public UnaryInstruction { + /// @brief Copy constructor + CastInst(const CastInst &CI) + : UnaryInstruction(CI.getType(), CI.getOpcode(), CI.getOperand(0)) { + } + /// @brief Do not allow default construction + CastInst(); +protected: + /// @brief Constructor with insert-before-instruction semantics for subclasses + CastInst(const Type *Ty, unsigned iType, Value *S, + const std::string &Name = "", Instruction *InsertBefore = 0) + : UnaryInstruction(Ty, iType, S, Name, InsertBefore) { + } + /// @brief Constructor with insert-at-end-of-block semantics for subclasses + CastInst(const Type *Ty, unsigned iType, Value *S, + const std::string &Name, BasicBlock *InsertAtEnd) + : UnaryInstruction(Ty, iType, S, Name, InsertAtEnd) { + } +public: + /// Provides a way to construct any of the CastInst subclasses using an + /// opcode instead of the subclass's constructor. The opcode must be in the + /// CastOps category (Instruction::isCast(opcode) returns true). This + /// constructor has insert-before-instruction semantics to automatically + /// insert the new CastInst before InsertBefore (if it is non-null). + /// @brief Construct any of the CastInst subclasses + static CastInst *create( + Instruction::CastOps, ///< The opcode of the cast instruction + Value *S, ///< The value to be casted (operand 0) + const Type *Ty, ///< The type to which cast should be made + const std::string &Name = "", ///< Name for the instruction + Instruction *InsertBefore = 0 ///< Place to insert the instruction + ); + /// Provides a way to construct any of the CastInst subclasses using an + /// opcode instead of the subclass's constructor. The opcode must be in the + /// CastOps category. This constructor has insert-at-end-of-block semantics + /// to automatically insert the new CastInst at the end of InsertAtEnd (if + /// its non-null). + /// @brief Construct any of the CastInst subclasses + static CastInst *create( + Instruction::CastOps, ///< The opcode for the cast instruction + Value *S, ///< The value to be casted (operand 0) + const Type *Ty, ///< The type to which operand is casted + const std::string &Name, ///< The name for the instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// Returns the opcode necessary to cast Val into Ty using usual casting + /// rules. + static Instruction::CastOps getCastOpcode( + const Value *Val, ///< The value to cast + const Type *Ty ///< The Type to which the value should be casted + ); + + /// Joins the create method (with insert-before-instruction semantics) above + /// with the getCastOpcode method. getOpcode(S,Ty) is called first to + /// obtain the opcode for casting S to type Ty. Then the get(...) method is + /// called to create the CastInst and insert it. The instruction is + /// inserted before InsertBefore (if it is non-null). The cast created is + /// inferred, because only the types involved are used in determining which + /// cast opcode to use. For specific casts, use one of the create methods. + /// @brief Inline helper method to join create with getCastOpcode. + inline static CastInst *createInferredCast( + Value *S, ///< The value to be casted (operand 0) + const Type *Ty, ///< Type to which operand should be casted + const std::string &Name = "", ///< Name for the instruction + Instruction *InsertBefore = 0 ///< Place to insert the CastInst + ) { + return create(getCastOpcode(S, Ty), S, Ty, Name, InsertBefore); + } + + /// Joins the get method (with insert-at-end-of-block semantics) method + /// above with the getCastOpcode method. getOpcode(S,Ty) is called first to + /// obtain the usual casting opcode for casting S to type Ty. Then the + /// get(...) method is called to create the CastInst and insert it. The + /// instruction is inserted at the end of InsertAtEnd (if it is non-null). + /// The created cast is inferred, because only the types involved are used + /// in determining which cast opcode to use. For specific casts, use one of + /// the create methods. + /// @brief Inline helper method to join create with getCastOpcode. + inline static CastInst *createInferredCast( + Value *S, ///< The value to be casted (operand 0) + const Type *Ty, ///< Type to which operand should be casted + const std::string &Name, ///< Name for the instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ) { + return create(getCastOpcode(S, Ty), S, Ty, Name, InsertAtEnd); + } + + /// There are several places where we need to know if a cast instruction + /// only deals with integer source and destination types. To simplify that + /// logic, this method is provided. + /// @returns true iff the cast has only integral typed operand and dest type. + /// @brief Determine if this is an integer-only cast. + bool isIntegerCast() const; + + /// A lossless cast is one that does not alter the basic value. It implies + /// a no-op cast but is more stringent, preventing things like int->float, + /// long->double, int->ptr, or packed->anything. + /// @returns true iff the cast is lossless. + /// @brief Determine if this is a lossless cast. + bool isLosslessCast() const; + + /// A no-op cast is one that can be effected without changing any bits. + /// It implies that the source and destination types are the same size. The + /// IntPtrTy argument is used to make accurate determinations for casts + /// involving Integer and Pointer types. They are no-op casts if the integer + /// is the same size as the pointer. However, pointer size varies with + /// platform. Generally, the result of TargetData::getIntPtrType() should be + /// passed in. If that's not available, use Type::ULongTy, which will make + /// the isNoopCast call conservative. + /// @brief Determine if this cast is a no-op cast. + bool isNoopCast( + const Type *IntPtrTy ///< Integer type corresponding to pointer + ) const; + + /// Determine how a pair of casts can be eliminated, if they can be at all. + /// This is a helper function for both CastInst and ConstantExpr. + /// @returns 0 if the CastInst pair can't be eliminated + /// @returns Instruction::CastOps value for a cast that can replace + /// the pair, casting SrcTy to DstTy. + /// @brief Determine if a cast pair is eliminable + static unsigned isEliminableCastPair( + Instruction::CastOps firstOpcode, ///< Opcode of first cast + Instruction::CastOps secondOpcode, ///< Opcode of second cast + const Type *SrcTy, ///< SrcTy of 1st cast + const Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast + const Type *DstTy, ///< DstTy of 2nd cast + const Type *IntPtrTy ///< Integer type corresponding to Ptr types + ); + + /// @brief Return the opcode of this CastInst + Instruction::CastOps getOpcode() const { + return Instruction::CastOps(Instruction::getOpcode()); + } + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const CastInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// // CmpInst Class //===----------------------------------------------------------------------===// diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index 55c668ab1a..dac14d33bd 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -60,6 +60,20 @@ #define LAST_MEMORY_INST(num) #endif +#ifndef FIRST_CAST_INST +#define FIRST_CAST_INST(num) +#endif +#ifndef HANDLE_CAST_INST +#ifndef HANDLE_INST +#define HANDLE_CAST_INST(num, opcode, Class) +#else +#define HANDLE_CAST_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class) +#endif +#endif +#ifndef LAST_CAST_INST +#define LAST_CAST_INST(num) +#endif + #ifndef FIRST_OTHER_INST #define FIRST_OTHER_INST(num) #endif @@ -124,24 +138,41 @@ HANDLE_MEMORY_INST(29, Store , StoreInst ) HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst) LAST_MEMORY_INST(30) +// Cast operators ... +// NOTE: The order matters here because CastInst::isEliminableCastPair +// NOTE: (see Instructions.cpp) encodes a table based on this ordering. + FIRST_CAST_INST(31) +HANDLE_CAST_INST(31, Trunc , CastInst ) // Truncate integers +HANDLE_CAST_INST(32, ZExt , CastInst ) // Zero extend integers +HANDLE_CAST_INST(33, SExt , CastInst ) // Sign extend integers +HANDLE_CAST_INST(34, FPToUI , CastInst ) // floating point -> UInt +HANDLE_CAST_INST(35, FPToSI , CastInst ) // floating point -> SInt +HANDLE_CAST_INST(36, UIToFP , CastInst ) // UInt -> floating point +HANDLE_CAST_INST(37, SIToFP , CastInst ) // SInt -> floating point +HANDLE_CAST_INST(38, FPTrunc , CastInst ) // Truncate floating point +HANDLE_CAST_INST(39, FPExt , CastInst ) // Extend floating point +HANDLE_CAST_INST(40, PtrToInt, CastInst ) // Pointer -> Integer +HANDLE_CAST_INST(41, IntToPtr, CastInst ) // Integer -> Pointer +HANDLE_CAST_INST(42, BitCast , CastInst ) // Type cast + LAST_CAST_INST(42) + // Other operators... - FIRST_OTHER_INST(31) -HANDLE_OTHER_INST(31, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(32, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(33, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(34, Cast , CastInst ) // Type cast -HANDLE_OTHER_INST(35, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(36, Shl , ShiftInst ) // Shift Left operations (logical) -HANDLE_OTHER_INST(37, LShr , ShiftInst ) // Logical Shift right (unsigned) -HANDLE_OTHER_INST(38, AShr , ShiftInst ) // Arithmetic shift right (signed) -HANDLE_OTHER_INST(39, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(40, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(41, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(42, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(43, ExtractElement, ExtractElementInst)// extract from vector. -HANDLE_OTHER_INST(44, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(45, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. - LAST_OTHER_INST(45) + FIRST_OTHER_INST(43) +HANDLE_OTHER_INST(43, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(44, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(45, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(46, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(47, Shl , ShiftInst ) // Shift Left operations (logical) +HANDLE_OTHER_INST(48, LShr , ShiftInst ) // Logical Shift right (unsigned) +HANDLE_OTHER_INST(49, AShr , ShiftInst ) // Arithmetic shift right (signed) +HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector. +HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. + LAST_OTHER_INST(56) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST @@ -155,6 +186,10 @@ HANDLE_OTHER_INST(45, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. #undef HANDLE_MEMORY_INST #undef LAST_MEMORY_INST +#undef FIRST_CAST_INST +#undef HANDLE_CAST_INST +#undef LAST_CAST_INST + #undef FIRST_OTHER_INST #undef HANDLE_OTHER_INST #undef LAST_OTHER_INST diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 591e0d2b88..4af83c7a56 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -125,6 +125,16 @@ public: return getOpcode() >= BinaryOpsBegin && getOpcode() < BinaryOpsEnd; } + /// @brief Determine if the OpCode is one of the CastInst instructions. + static inline bool isCast(unsigned OpCode) { + return OpCode >= CastOpsBegin && OpCode < CastOpsEnd; + } + + /// @brief Determine if this is one of the CastInst instructions. + inline bool isCast() const { + return isCast(getOpcode()); + } + /// isAssociative - Return true if the instruction is associative: /// /// Associative operators satisfy: x op (y op z) === (x op y) op z @@ -191,6 +201,13 @@ public: #include "llvm/Instruction.def" }; + enum CastOps { +#define FIRST_CAST_INST(N) CastOpsBegin = N, +#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N, +#define LAST_CAST_INST(N) CastOpsEnd = N+1 +#include "llvm/Instruction.def" + }; + enum OtherOps { #define FIRST_OTHER_INST(N) OtherOpsBegin = N, #define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N, diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 8046567fde..5f7125678d 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -710,44 +710,6 @@ public: } }; -//===----------------------------------------------------------------------===// -// CastInst Class -//===----------------------------------------------------------------------===// - -/// CastInst - This class represents a cast from Operand[0] to the type of -/// the instruction (i->getType()). -/// -class CastInst : public UnaryInstruction { - CastInst(const CastInst &CI) - : UnaryInstruction(CI.getType(), Cast, CI.getOperand(0)) { - } -public: - CastInst(Value *S, const Type *Ty, const std::string &Name = "", - Instruction *InsertBefore = 0) - : UnaryInstruction(Ty, Cast, S, Name, InsertBefore) { - } - CastInst(Value *S, const Type *Ty, const std::string &Name, - BasicBlock *InsertAtEnd) - : UnaryInstruction(Ty, Cast, S, Name, InsertAtEnd) { - } - - /// isTruncIntCast - Return true if this is a truncating integer cast - /// instruction, e.g. a cast from long to uint. - bool isTruncIntCast() const; - - - virtual CastInst *clone() const; - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CastInst *) { return true; } - static inline bool classof(const Instruction *I) { - return I->getOpcode() == Cast; - } - static inline bool classof(const Value *V) { - return isa<Instruction>(V) && classof(cast<Instruction>(V)); - } -}; - //===----------------------------------------------------------------------===// // CallInst Class @@ -1770,6 +1732,477 @@ private: virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; +//===----------------------------------------------------------------------===// +// TruncInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a truncation of integer types. +class TruncInst : public CastInst { + /// Private copy constructor + TruncInst(const TruncInst &CI) + : CastInst(CI.getType(), Trunc, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + TruncInst( + Value *S, ///< The value to be truncated + const Type *Ty, ///< The (smaller) type to truncate to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + TruncInst( + Value *S, ///< The value to be truncated + const Type *Ty, ///< The (smaller) type to truncate to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical TruncInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const TruncInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Trunc; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// ZExtInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents zero extension of integer types. +class ZExtInst : public CastInst { + /// @brief Private copy constructor + ZExtInst(const ZExtInst &CI) + : CastInst(CI.getType(), ZExt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + ZExtInst( + Value *S, ///< The value to be zero extended + const Type *Ty, ///< The type to zero extend to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end semantics. + ZExtInst( + Value *S, ///< The value to be zero extended + const Type *Ty, ///< The type to zero extend to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical ZExtInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ZExtInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == ZExt; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// SExtInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a sign extension of integer types. +class SExtInst : public CastInst { + /// @brief Private copy constructor + SExtInst(const SExtInst &CI) + : CastInst(CI.getType(), SExt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + SExtInst( + Value *S, ///< The value to be sign extended + const Type *Ty, ///< The type to sign extend to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + SExtInst( + Value *S, ///< The value to be sign extended + const Type *Ty, ///< The type to sign extend to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical SExtInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SExtInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == SExt; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPTruncInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a truncation of floating point types. +class FPTruncInst : public CastInst { + FPTruncInst(const FPTruncInst &CI) + : CastInst(CI.getType(), FPTrunc, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + FPTruncInst( + Value *S, ///< The value to be truncated + const Type *Ty, ///< The type to truncate to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-before-instruction semantics + FPTruncInst( + Value *S, ///< The value to be truncated + const Type *Ty, ///< The type to truncate to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical FPTruncInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPTruncInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPTrunc; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPExtInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents an extension of floating point types. +class FPExtInst : public CastInst { + FPExtInst(const FPExtInst &CI) + : CastInst(CI.getType(), FPExt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + FPExtInst( + Value *S, ///< The value to be extended + const Type *Ty, ///< The type to extend to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + FPExtInst( + Value *S, ///< The value to be extended + const Type *Ty, ///< The type to extend to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical FPExtInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPExtInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPExt; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// UIToFPInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast unsigned integer to floating point. +class UIToFPInst : public CastInst { + UIToFPInst(const UIToFPInst &CI) + : CastInst(CI.getType(), UIToFP, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + UIToFPInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + UIToFPInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical UIToFPInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const UIToFPInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == UIToFP; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// SIToFPInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from signed integer to floating point. +class SIToFPInst : public CastInst { + SIToFPInst(const SIToFPInst &CI) + : CastInst(CI.getType(), SIToFP, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + SIToFPInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + SIToFPInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical SIToFPInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SIToFPInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == SIToFP; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPToUIInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from floating point to unsigned integer +class FPToUIInst : public CastInst { + FPToUIInst(const FPToUIInst &CI) + : CastInst(CI.getType(), FPToUI, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + FPToUIInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + FPToUIInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< Where to insert the new instruction + ); + + /// @brief Clone an identical FPToUIInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPToUIInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPToUI; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// FPToSIInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from floating point to signed integer. +class FPToSIInst : public CastInst { + FPToSIInst(const FPToSIInst &CI) + : CastInst(CI.getType(), FPToSI, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + FPToSIInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + FPToSIInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical FPToSIInst + virtual CastInst *clone() const; + + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FPToSIInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == FPToSI; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// IntToPtrInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from an integer to a pointer. +class IntToPtrInst : public CastInst { + IntToPtrInst(const IntToPtrInst &CI) + : CastInst(CI.getType(), IntToPtr, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + IntToPtrInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + IntToPtrInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical IntToPtrInst + virtual CastInst *clone() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const IntToPtrInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == IntToPtr; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// PtrToIntInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a cast from a pointer to an integer +class PtrToIntInst : public CastInst { + PtrToIntInst(const PtrToIntInst &CI) + : CastInst(CI.getType(), PtrToInt, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + PtrToIntInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + PtrToIntInst( + Value *S, ///< The value to be converted + const Type *Ty, ///< The type to convert to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical PtrToIntInst + virtual CastInst *clone() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const PtrToIntInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == PtrToInt; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +//===----------------------------------------------------------------------===// +// BitCastInst Class +//===----------------------------------------------------------------------===// + +/// @brief This class represents a no-op cast from one type to another. +class BitCastInst : public CastInst { + BitCastInst(const BitCastInst &CI) + : CastInst(CI.getType(), BitCast, CI.getOperand(0)) { + } +public: + /// @brief Constructor with insert-before-instruction semantics + BitCastInst( + Value *S, ///< The value to be casted + const Type *Ty, ///< The type to casted to + const std::string &Name = "", ///< A name for the new instruction + Instruction *InsertBefore = 0 ///< Where to insert the new instruction + ); + + /// @brief Constructor with insert-at-end-of-block semantics + BitCastInst( + Value *S, ///< The value to be casted + const Type *Ty, ///< The type to casted to + const std::string &Name, ///< A name for the new instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Clone an identical BitCastInst + virtual CastInst *clone() const; + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const BitCastInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == BitCast; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + } // End llvm namespace #endif diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 713980a86b..e3103a4c38 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -143,7 +143,6 @@ public: void visitFunction (Function &F) {} void visitBasicBlock(BasicBlock &BB) {} - // Define instruction specific visitor functions that can be overridden to // handle SPECIFIC instructions. These functions automatically define // visitMul to proxy to visitBinaryOperator for instance in case the user does @@ -183,7 +182,7 @@ public: RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); } RetTy visitShiftInst(ShiftInst &I) { DELEGATE(Instruction); } RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); } - RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction); } + RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);} RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); } RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index 56f7a9c4f9..2974ad39d4 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -10,7 +10,7 @@ // This file provides a simple and efficient mechanism for performing general // tree-based pattern matches on the LLVM IR. The power of these routines is // that it allows you to write concise patterns that are expressive and easy to -// understand. The other major advantage of this is that is allows to you +// understand. The other major advantage of this is that it allows you to // trivially capture/bind elements in the pattern to variables. For example, // you can do something like this: // @@ -336,38 +336,6 @@ template<typename LHS> inline not_match<LHS> m_Not(const LHS &L) { return L; } -template<typename Op_t> -struct cast_match { - Op_t Op; - const Type **DestTy; - - cast_match(const Op_t &op, const Type **destTy) : Op(op), DestTy(destTy) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (CastInst *I = dyn_cast<CastInst>(V)) { - if (DestTy) *DestTy = I->getType(); - return Op.match(I->getOperand(0)); - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::Cast) { - if (DestTy) *DestTy = CE->getType(); - return Op.match(CE->getOperand(0)); - } - } - return false; - } -}; - -template<typename Op_t> -inline cast_match<Op_t> m_Cast(const Op_t &Op, const Type *&Ty) { - return cast_match<Op_t>(Op, &Ty); -} -template<typename Op_t> -inline cast_match<Op_t> m_Cast(const Op_t &Op) { - return cast_match<Op_t>(Op, 0); -} - - //===----------------------------------------------------------------------===// // Matchers for control flow // diff --git a/include/llvm/Type.h b/include/llvm/Type.h index dab6c127cd..6f1957414a 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -194,10 +194,12 @@ public: /// inline bool isAbstract() const { return Abstract; } - /// isLosslesslyConvertibleTo - Return true if this type can be converted to - /// 'Ty' without any reinterpretation of bits. For example, uint to int. - /// - bool isLosslesslyConvertibleTo(const Type *Ty) const; + /// canLosslesslyBitCastTo - Return true if this type could be converted + /// with a lossless BitCast to type 'Ty'. For example, uint to int. BitCasts + /// are valid for types of the same size only where no re-interpretation of + /// the bits is done. + /// @brief Determine if this type could be losslessly bitcast to Ty + bool canLosslesslyBitCastTo(const Type *Ty) const; /// Here are some useful little methods to query what type derived types are diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index ec1a72b951..a7269ffa09 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -129,27 +129,23 @@ ImmutablePass *llvm::createBasicAliasAnalysisPass() { return new BasicAliasAnalysis(); } -// hasUniqueAddress - Return true if the specified value points to something -// with a unique, discernable, address. -static inline bool hasUniqueAddress(const Value *V) { - return isa<GlobalValue>(V) || isa<AllocationInst>(V); -} - // getUnderlyingObject - This traverses the use chain to figure out what object // the specified value points to. If the value points to, or is derived from, a // unique object or an argument, return it. static const Value *getUnderlyingObject(const Value *V) { if (!isa<PointerType>(V->getType())) return 0; - // If we are at some type of object... return it. - if (hasUniqueAddress(V) || isa<Argument>(V)) return V; + // If we are at some type of object, return it. GlobalValues and Allocations + // have unique addresses. + if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isa<Argument>(V)) + return V; // Traverse through different addressing mechanisms... if (const Instruction *I = dyn_cast<Instruction>(V)) { - if (isa<CastInst>(I) || isa<GetElementPtrInst>(I)) + if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I)) return getUnderlyingObject(I->getOperand(0)); } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::Cast || + if (CE->getOpcode() == Instruction::BitCast || CE->getOpcode() == Instruction::GetElementPtr) return getUnderlyingObject(CE->getOperand(0)); } @@ -192,28 +188,34 @@ bool BasicAliasAnalysis::pointsToConstantMemory(const Value *P) { return false; } +// Determine if an AllocationInst instruction escapes from the function it is +// contained in. If it does not escape, there is no way for another function to +// mod/ref it. We do this by looking at its uses and determining if the uses +// can escape (recursively). static bool AddressMightEscape(const Value *V) { for (Value::use_const_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI) { const Instruction *I = cast<Instruction>(*UI); switch (I->getOpcode()) { - case Instruction::Load: break; + case Instruction::Load: + break; //next use. case Instruction::Store: if (I->getOperand(0) == V) return true; // Escapes if the pointer is stored. - break; + break; // next use. case Instruction::GetElementPtr: - if (AddressMightEscape(I)) return true; - break; - case Instruction::Cast: + if (AddressMightEscape(I)) + return true; + case Instruction::BitCast: if (!isa<PointerType>(I->getType())) return true; - if (AddressMightEscape(I)) return true; - break; + if (AddressMightEscape(I)) + return true; + break; // next use case Instruction::Ret: // If returned, the address will escape to calling functions, but no // callees could modify it. - break; + break; // next use default: return true; } @@ -257,12 +259,10 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size) { // Strip off any constant expression casts if they exist if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V1)) - if (CE->getOpcode() == Instruction::Cast && - isa<PointerType>(CE->getOperand(0)->getType())) + if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType())) V1 = CE->getOperand(0); if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V2)) - if (CE->getOpcode() == Instruction::Cast && - isa<PointerType>(CE->getOperand(0)->getType())) + if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType())) V2 = CE->getOperand(0); // Are we checking for alias of the same value? @@ -273,10 +273,10 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, return NoAlias; // Scalars cannot alias each other // Strip off cast instructions... - if (const Instruction *I = dyn_cast<CastInst>(V1)) + if (const BitCastInst *I = dyn_cast<BitCastInst>(V1)) if (isa<PointerType>(I->getOperand(0)->getType())) return alias(I->getOperand(0), V1Size, V2, V2Size); - if (const Instruction *I = dyn_cast<CastInst>(V2)) + if (const BitCastInst *I = dyn_cast<BitCastInst>(V2)) if (isa<PointerType>(I->getOperand(0)->getType())) return alias(V1, V1Size, I->getOperand(0), V2Size); @@ -450,14 +450,22 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, return MayAlias; } -static bool ValuesEqual(Value *V1, Value *V2) { +// This function is used to determin if the indices of two GEP instructions are +// equal. V1 and V2 are the indices. +static bool IndexOperandsEqual(Value *V1, Value *V2) { if (V1->getType() == V2->getType()) return V1 == V2; if (Constant *C1 = dyn_cast<Constant>(V1)) if (Constant *C2 = dyn_cast<Constant>(V2)) { - // Sign extend the constants to long types. - C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); - C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); + // Sign extend the constants to long types, if necessary + if (C1->getType()->getPrimitiveSizeInBits() < 64) + C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); + else if (C1->getType() == Type::ULongTy) + C1 = ConstantExpr::getBitCast(C1, Type::LongTy); + if (C2->getType()->getPrimitiveSizeInBits() < 64) + C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); + else if (C2->getType() == Type::ULongTy) + C2 = ConstantExpr::getBitCast(C2, Type::LongTy); return C1 == C2; } return false; @@ -485,7 +493,7 @@ BasicAliasAnalysis::CheckGEPInstructions( unsigned MaxOperands = std::max(NumGEP1Operands, NumGEP2Operands); unsigned UnequalOper = 0; while (UnequalOper != MinOperands && - ValuesEqual(GEP1Ops[UnequalOper], GEP2Ops[UnequalOper])) { + IndexOperandsEqual(GEP1Ops[UnequalOper], GEP2Ops[UnequalOper])) { // Advance through the type as we go... ++UnequalOper; if (const CompositeType *CT = dyn_cast<CompositeType>(BasePtr1Ty)) @@ -546,8 +554,14 @@ BasicAliasAnalysis::CheckGEPInstructions( if (Constant *G2OC = dyn_cast<ConstantInt>(const_cast<Value*>(G2Oper))){ if (G1OC->getType() != G2OC->getType()) { // Sign extend both operands to long. - G1OC = ConstantExpr::getSignExtend(G1OC, Type::LongTy); - G2OC = ConstantExpr::getSignExtend(G2OC, Type::LongTy); + if (G1OC->getType()->getPrimitiveSizeInBits() < 64) + G1OC = ConstantExpr::getSignExtend(G1OC, Type::LongTy); + else if (G1OC->getType() == Type::ULongTy) + G1OC = ConstantExpr::getBitCast(G1OC, Type::LongTy); + if (G2OC->getType()->getPrimitiveSizeInBits() < 64) + G2OC = ConstantExpr::getSignExtend(G2OC, Type::LongTy); + else if (G2OC->getType() == Type::ULongTy) + G2OC = ConstantExpr::getBitCast(G2OC, Type::LongTy); GEP1Ops[FirstConstantOper] = G1OC; GEP2Ops[FirstConstantOper] = G2OC; } diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index 505fe91362..8b8bde0026 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/lib/Analysis/DataStructure/DataStructure.cpp @@ -410,7 +410,7 @@ static bool ElementTypesAreCompatible(const Type *T1, const Type *T2, const Type *T1 = T1W.getCurrentType(); const Type *T2 = T2W.getCurrentType(); - if (T1 != T2 && !T1->isLosslesslyConvertibleTo(T2)) + if (T1 != T2 && !T1->canLosslesslyBitCastTo(T2)) return false; T1W.StepToNextType(); @@ -701,7 +701,7 @@ bool DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset, // Check to see if we have a compatible, but different type... if (NewTySize == SubTypeSize) { // Check to see if this type is obviously convertible... int -> uint f.e. - if (NewTy->isLosslesslyConvertibleTo(SubType)) + if (NewTy->canLosslesslyBitCastTo(SubType)) return false; // Check to see if we have a pointer & integer mismatch going on here, diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp index c8880c11c5..34947371c6 100644 --- a/lib/Analysis/DataStructure/Local.cpp +++ b/lib/Analysis/DataStructure/Local.cpp @@ -240,7 +240,7 @@ DSNodeHandle GraphBuilder::getValueDest(Value &Val) { N->addGlobal(GV); } else if (Constant *C = dyn_cast<Constant>(V)) { if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { - if (CE->getOpcode() == Instruction::Cast) { + if (CE->isCast()) { if (isa<PointerType>(CE->getOperand(0)->getType())) NH = getValueDest(*CE->getOperand(0)); else @@ -1091,20 +1091,27 @@ void GraphBuilder::visitFreeInst(FreeInst &FI) { /// Handle casts... void GraphBuilder::visitCastInst(CastInst &CI) { - if (isPointerType(CI.getType())) - if (isPointerType(CI.getOperand(0)->getType())) { - DSNodeHandle Ptr = getValueDest(*CI.getOperand(0)); - if (Ptr.getNode() == 0) return; - - // Cast one pointer to the other, just act like a copy instruction - setDestTo(CI, Ptr); - } else { - // Cast something (floating point, small integer) to a pointer. We need - // to track the fact that the node points to SOMETHING, just something we - // don't know about. Make an "Unknown" node. - // - setDestTo(CI, createNode()->setUnknownNodeMarker()); - } + // Pointers can only be cast with BitCast so check that the instruction + // is a BitConvert. If not, its guaranteed not to involve any pointers so + // we don't do anything. + switch (CI.getOpcode()) { + default: break; + case Instruction::BitCast: + case Instruction::IntToPtr: + if (isPointerType(CI.getType())) + if (isPointerType(CI.getOperand(0)->getType())) { + DSNodeHandle Ptr = getValueDest(*CI.getOperand(0)); + if (Ptr.getNode() == 0) return; + // Cast one pointer to the other, just act like a copy instruction + setDestTo(CI, Ptr); + } else { + // Cast something (floating point, small integer) to a pointer. We + // need to track the fact that the node points to SOMETHING, just + // something we don't know about. Make an "Unknown" node. + setDestTo(CI, createNode()->setUnknownNodeMarker()); + } + break; + } } diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp index dd94b3832d..73aa231e21 100644 --- a/lib/Analysis/IPA/Andersens.cpp +++ b/lib/Analysis/IPA/Andersens.cpp @@ -529,11 +529,10 @@ Andersens::Node *Andersens::getNodeForConstantPointer(Constant *C) { switch (CE->getOpcode()) { case Instruction::GetElementPtr: return getNodeForConstantPointer(CE->getOperand(0)); - case Instruction::Cast: - if (isa<PointerType>(CE->getOperand(0)->getType())) - return getNodeForConstantPointer(CE->getOperand(0)); - else - return &GraphNodes[UniversalSet]; + case Instruction::IntToPtr: + return &GraphNodes[UniversalSet]; + case Instruction::BitCast: + return getNodeForConstantPointer(CE->getOperand(0)); default: std::cerr << "Constant Expr not yet handled: " << *CE << "\n"; assert(0); @@ -557,11 +556,10 @@ Andersens::Node *Andersens::getNodeForConstantPointerTarget(Constant *C) { switch (CE->getOpcode()) { case Instruction::GetElementPtr: return getNodeForConstantPointerTarget(CE->getOperand(0)); - case Instruction::Cast: - if (isa<PointerType>(CE->getOperand(0)->getType())) - return getNodeForConstantPointerTarget(CE->getOperand(0)); - else - return &GraphNodes[UniversalSet]; + case Instruction::IntToPtr: + return &GraphNodes[UniversalSet]; + case Instruction::BitCast: + return getNodeForConstantPointerTarget(CE->getOperand(0)); default: std::cerr << "Constant Expr not yet handled: " << *CE << "\n"; assert(0); diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index d4dc18dc71..59cf66f6c3 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -167,10 +167,10 @@ static Value *getUnderlyingObject(Value *V) { // Traverse through different addressing mechanisms. if (Instruction *I = dyn_cast<Instruction>(V)) { - if (isa<CastInst>(I) || isa<GetElementPtrInst>(I)) + if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I)) return getUnderlyingObject(I->getOperand(0)); } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::Cast || + if (CE->getOpcode() == Instruction::BitCast || CE->getOpcode() == Instruction::GetElementPtr) return getUnderlyingObject(CE->getOperand(0)); } @@ -252,8 +252,8 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V, for (unsigned i = 3, e = II->getNumOperands(); i != e; ++i) if (II->getOperand(i) == V) return true; } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) { - if (CE->getOpcode() == Instruction::GetElementPtr || - CE->getOpcode() == Instruction::Cast) { + if (CE->getOpcode() == Instruction::GetElementPtr || + CE->getOpcode() == Instruction::BitCast) { if (AnalyzeUsesOfPointer(CE, Readers, Writers)) return true; } else { diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index cd7000503c..8c809f8c5a 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -203,7 +203,6 @@ static ManagedStatic<std::map<std::pair<SCEV*, const Type*>, SCEVTruncateExpr::SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) : SCEV(scTruncate), Op(op), Ty(ty) { assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && "Cannot truncate non-integer value!"); assert(Op->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() && "This is not a truncating conversion!"); @@ -230,7 +229,6 @@ static ManagedStatic<std::map<std::pair<SCEV*, const Type*>, SCEVZeroExtendExpr::SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) : SCEV(scZeroExtend), Op(op), Ty(ty) { assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && "Cannot zero extend non-integer value!"); assert(Op->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() && "This is not an extending conversion!"); @@ -1139,7 +1137,6 @@ namespace { /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. SCEVHandle createSCEV(Value *V); - SCEVHandle createNodeForCast(CastInst *CI); /// createNodeForPHI - Provide the special handling we need to analyze PHI /// SCEVs. @@ -1341,35 +1338,6 @@ SCEVHandle ScalarEvolutionsImpl::createNodeForPHI(PHINode *PN) { return SCEVUnknown::get(PN); } -/// createNodeForCast - Handle the various forms of casts that we support. -/// -SCEVHandle ScalarEvolutionsImpl::createNodeForCast(CastInst *CI) { - const Type *SrcTy = CI->getOperand(0)->getType(); - const Type *DestTy = CI->getType(); - - // If this is a noop cast (ie, conversion from int to uint), ignore it. - if (SrcTy->isLosslesslyConvertibleTo(DestTy)) - return getSCEV(CI->getOperand(0)); - - if (SrcTy->isInteger() && DestTy->isInteger()) { - // Otherwise, if this is a truncating integer cast, we can represent this - // cast. - if (SrcTy->getPrimitiveSize() > DestTy->getPrimitiveSize()) - return SCEVTruncateExpr::get(getSCEV(CI->getOperand(0)), - CI->getType()->getUnsignedVersion()); - if (SrcTy->isUnsigned() && - SrcTy->getPrimitiveSize() <= DestTy->getPrimitiveSize()) - return SCEVZeroExtendExpr::get(getSCEV(CI->getOperand(0)), - CI->getType()->getUnsignedVersion()); - } - - // If this is an sign or zero extending cast and we can prove that the value - // will never overflow, we could do similar transformations. - - // Otherwise, we can't handle this cast! - return SCEVUnknown::get(CI); -} - /// createSCEV - We know that there is no SCEV for the specified value. /// Analyze the expression. @@ -1401,8 +1369,21 @@ SCEVHandle ScalarEvolutionsImpl::createSCEV(Value *V) { } break; - case Instruction::Cast: - return createNodeForCast(cast<CastInst>(I)); + case Instruction::Trunc: + if (I->getType()->isInteger() && I->getOperand(0)->getType()->isInteger()) + return SCEVTruncateExpr::get(getSCEV(I->getOperand(0)), + I->getType()->getUnsignedVersion()); + break; + + case Instruction::ZExt: + if (I->getType()->isInteger() && I->getOperand(0)->getType()->isInteger()) + return SCEVZeroExtendExpr::get(getSCEV(I->getOperand(0)), + I->getType()->getUnsignedVersion()); + break; + + case Instruction::BitCast: + // BitCasts are no-op casts so we just eliminate the cast. + return getSCEV(I->getOperand(0)); case Instruction::PHI: return createNodeForPHI(cast<PHINode>(I)); @@ -1724,9 +1705,10 @@ static Constant *ConstantFold(const Instruction *I, if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) return ConstantExpr::get(I->getOpcode(), Operands[0], Operands[1]); + if (isa<CastInst>(I)) + return ConstantExpr::getCast(I->getOpcode(), Operands[0], I->getType()); + switch (I->getOpcode()) { - case Instruction::Cast: - return ConstantExpr::getCast(Operands[0], I->getType()); case Instruction::Select: return ConstantExpr::getSelect(Operands[0], Operands[1], Operands[2]); case Instruction::Call: @@ -1734,7 +1716,6 @@ static Constant *ConstantFold(const Instruction *I, Operands.erase(Operands.begin()); return ConstantFoldCall(cast<Function>(GV), Operands); } - return 0; case Instruction::GetElementPtr: Constant *Base = Operands[0]; diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index 68b52dd4fa..b6d77b93ae 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -30,8 +30,7 @@ Value *SCEVExpander::InsertCastOfTo(Value *V, const Type *Ty) { UI != E; ++UI) { if ((*UI)->getType() == Ty) if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI))) { - // If the cast isn't in the first instruction of the function, - // move it. + // If the cast isn't the first instruction of the function, move it. if (BasicBlock::iterator(CI) != A->getParent()->getEntryBlock().begin()) { CI->moveBefore(A->getParent()->getEntryBlock().begin()); @@ -39,8 +38,8 @@ Value *SCEVExpander::InsertCastOfTo(Value *V, const Type *Ty) { return CI; } } - return new CastInst(V, Ty, V->getName(), - A->getParent()->getEntryBlock().begin()); + return CastInst::createInferredCast(V, Ty, V->getName(), + A->getParent()->getEntryBlock().begin()); } Instruction *I = cast<Instruction>(V); @@ -65,7 +64,7 @@ Value *SCEVExpander::InsertCastOfTo(Value *V, const Type *Ty) { if (InvokeInst *II = dyn_cast<InvokeInst>(I)) IP = II->getNormalDest()->begin(); while (isa<PHINode>(IP)) ++IP; - return new CastInst(V, Ty, V->getName(), IP); + return CastInst::createInferredCast(V, Ty, V->getName(), IP); } Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) { diff --git a/lib/Analysis/ValueNumbering.cpp b/lib/Analysis/ValueNumbering.cpp index 03b9f6b3ea..73d7ed3e4a 100644 --- a/lib/Analysis/ValueNumbering.cpp +++ b/lib/Analysis/ValueNumbering.cpp @@ -113,8 +113,10 @@ void BVNImpl::visitCastInst(CastInst &CI) { for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end(); UI != UE; ++UI) if (CastInst *Other = dyn_cast<CastInst>(*UI)) - // Check that the types are the same, since this code handles casts... - if (Other->getType() == I.getType() && + // Check that the opcode is the same + if (Other->getOpcode() == Instruction::CastOps(I.getOpcode()) && + // Check that the destination types are the same + Other->getType() == I.getType() && // Is it embedded in the same function? (This could be false if LHS // is a constant or global!) Other->getParent()->getParent() == F && diff --git a/lib/AsmParser/Lexer.cpp.cvs b/lib/AsmParser/Lexer.cpp.cvs index 9d6db6673d..1ff6e5a705 100644 --- a/lib/AsmParser/Lexer.cpp.cvs +++ b/lib/AsmParser/Lexer.cpp.cvs @@ -17,7 +17,7 @@ #define yylineno llvmAsmlineno #line 20 "Lexer.cpp" -/* A lexical scanner generated by flex */ +/* A lexical scanner generated by flex*/ /* Scanner skeleton version: * $Header$ @@ -28,6 +28,7 @@ #define YY_FLEX_MINOR_VERSION 5 #include <stdio.h> +#include <unistd.h> /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ @@ -41,7 +42,6 @@ #ifdef __cplusplus #include <stdlib.h> -#include <unistd.h> /* Use prototypes in function declarations. */ #define YY_USE_PROTOS @@ -153,6 +153,15 @@ extern FILE *yyin, *yyout; #define unput(c) yyunput( c, yytext_ptr ) +/* Some routines like yy_flex_realloc() are emitted as static but are + not called by all lexers. This generates warnings in some compilers, + notably GCC. Arrange to suppress these. */ +#ifdef __GNUC__ +#define YY_MAY_BE_UNUSED __attribute__((unused)) +#else +#define YY_MAY_BE_UNUSED +#endif + /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). @@ -259,7 +268,7 @@ YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static inline void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static inline void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED; static void yy_flex_free YY_PROTO(( void * )); #define yy_new_buffer yy_create_buffer @@ -308,35 +317,37 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); *yy_cp = '\0'; \ yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 120 -#define YY_END_OF_BUFFER 121 -static yyconst short int yy_acclist[198] = +#define YY_NUM_RULES 134 +#define YY_END_OF_BUFFER 135 +static yyconst short int yy_acclist[212] = { 0, - 121, 119, 120, 118, 119, 120, 118, 120, 119, 120, - 119, 120, 119, 120, 119, 120, 119, 120, 119, 120, - 111, 119, 120, 111, 119, 120, 1, 119, 120, 119, - 120, 119, 120, 119, 120, 119, 120, 119, 120, 119, - 120, 119, 120, 119, 120, 119, 120, 119, 120, 119, - 120, 119, 120, 119, 120, 119, 120, 119, 120, 119, - 120, 119, 120, 119, 120, 119, 120, 119, 120, 119, - 120, 110, 108, 107, 107, 114, 112, 116, 111, 1, - 93, 41, 75, 23, 110, 107, 107, 115, 116, 20, - 116, 117, 63, 74, 39, 34, 42, 66, 3, 54, - - 65, 25, 83, 70, 92, 87, 88, 64, 76, 109, - 116, 116, 49, 84, 85, 69, 100, 73, 101, 56, - 22, 113, 68, 72, 26, 4, 61, 67, 55, 71, - 48, 11, 116, 36, 2, 5, 58, 60, 50, 78, - 82, 80, 81, 79, 77, 52, 102, 51, 57, 21, - 90, 99, 45, 59, 30, 24, 44, 7, 95, 33, - 98, 38, 62, 86, 94, 27, 28, 96, 53, 91, - 89, 43, 6, 29, 37, 8, 17, 9, 10, 35, - 12, 14, 13, 32, 40, 15, 31, 97, 103, 105, - 106, 16, 46, 104, 18, 47, 19 - + 135, 133, 134, 132, 133, 134, 132, 134, 133, 134, + 133, 134, 133, 134, 133, 134, 133, 134, 133, 134, + 125, 133, 134, 125, 133, 134, 1, 133, 134, 133, + 134, 133, 134, 133, 134, 133, 134, 133, 134, 133, + 134, 133, 134, 133, 134, 133, 134, 133, 134, 133, + 134, 133, 134, 133, 134, 133, 134, 133, 134, 133, + 134, 133, 134, 133, 134, 133, 134, 133, 134, 133, + 134, 124, 122, 121, 121, 128, 126, 130, 125, 1, + 107, 41, 75, 23, 124, 121, 121, 129, 130, 20, + 130, 131, 63, 74, 39, 34, 42, 66, 3, 54, + + 65, 25, 83, 70, 106, 99, 100, 64, 76, 123, + 130, 130, 102, 49, 84, 85, 69, 114, 73, 115, + 56, 101, 22, 127, 68, 88, 72, 26, 4, 61, + 67, 55, 71, 48, 11, 87, 130, 36, 2, 5, + 58, 90, 60, 50, 78, 82, 80, 81, 79, 77, + 52, 116, 86, 51, 57, 21, 104, 113, 45, 59, + 30, 24, 44, 94, 93, 7, 109, 33, 112, 38, + 62, 98, 92, 108, 27, 28, 91, 110, 53, 105, + 103, 97, 43, 6, 29, 89, 37, 8, 17, 9, + 95, 10, 96, 35, 12, 14, 13, 32, 40, 15, + + 31, 111, 117, 119, 120, 16, 46, 118, 18, 47, + 19 } ; -static yyconst short int yy_accept[527] = +static yyconst short int yy_accept[577] = { 0, 1, 1, 1, 2, 4, 7, 9, 11, 13, 15, 17, 19, 21, 24, 27, 30, 32, 34, 36, 38, @@ -346,56 +357,61 @@ static yyconst short int yy_accept[527] = 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, - 87, 89, 90, 91, 92, 92, 93, 94, 94, 94, - 95, 95, 96, 96, 97, 97, 97, 97, 98, 98, - 98, 98, 98, 98, 98, 99, 99, 99, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, - 103, 103, 103, 104, 104, 105, 106, 106, 106, 106, + 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 86, 87, 89, 90, 91, 92, 92, 93, + 94, 94, 94, 95, 95, 95, 96, 96, 97, 97, + 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, + 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 102, 103, 103, + 103, 104, 104, 104, 105, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 108, 108, 108, 108, 108, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 110, 110, 111, 112, 112, 112, - 112, 113, 113, 113, 113, 113, 114, 115, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 117, 117, 118, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 120, 121, 121, - 121, 122, 122, 122, 123, 123, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 125, 125, 125, 126, - 126, 126, 127, 128, 128, 129, 130, 130, 130, 130, - 130, 130, 131, 131, 131, 131, 131, 132, 132, 133, - - 133, 133, 134, 135, 135, 135, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 137, 137, 138, 138, 138, 138, 138, 138, 138, 139, - 139, 139, 139, 139, 139, 139, 140, 140, 140, 141, - 142, 143, 144, 145, 146, 147, 147, 147, 148, 148, - 148, 148, 149, 150, 151, 151, 151, 151, 151, 151, - 152, 152, 152, 152, 152, 152, 153, 153, 154, 154, - 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, - 157, 158, 158, 159, 159, 159, 159, 160, 160, 161, - 162, 163, 164, 164, 164, 165, 165, 165, 166, 167, - - 168, 168, 168, 169, 170, 171, 172, 172, 172, 172, - 172, 172, 172, 173, 173, 174, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, - 177, 177, 177, 178, 178, 178, 178, 178, 179, 180, - 180, 180, 180, 180, 180, 181, 181, 181, 181, 182, - 182, 183, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 185, 185, 185, 185, - 185, 185, 185, 185, 186, 186, 186, 186, 186, 186, - 187, 187, 187, 187, 187, 188, 188, 188, 189, 189, - - 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 190, 190, 191, 192, 193, 193, 194, 194, - 195, 196, 197, 197, 198, 198 + 109, 109, 109, 109, 109, 109, 110, 110, 110, 111, + 112, 112, 112, 112, 113, 113, 113, 113, 114, 114, + 114, 115, 116, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 118, + 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 121, 122, 123, 123, + 123, 124, 124, 124, 124, 125, 125, 126, 126, 126, + 126, 126, 126, 126, 127, 127, 127, 127, 127, 128, + + 128, 128, 129, 129, 129, 130, 130, 131, 131, 132, + 133, 133, 133, 133, 133, 133, 133, 134, 134, 134, + 134, 134, 135, 135, 136, 136, 136, 137, 138, 139, + 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 141, 141, 142, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 144, 144, 144, 144, 144, 144, 144, 144, 145, + 145, 145, 146, 147, 148, 149, 150, 151, 152, 152, + 152, 152, 153, 153, 153, 153, 154, 155, 155, 156, + 157, 157, 157, 157, 157, 157, 158, 158, 158, 158, + + 158, 158, 159, 159, 159, 160, 160, 160, 160, 160, + 160, 160, 160, 161, 162, 163, 163, 163, 164, 165, + 166, 166, 166, 167, 167, 167, 167, 167, 168, 168, + 169, 170, 171, 172, 172, 172, 172, 173, 173, 173, + 174, 175, 176, 177, 178, 178, 178, 179, 180, 181, + 182, 182, 182, 182, 182, 182, 183, 183, 184, 184, + 185, 186, 186, 186, 186, 186, 186, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 188, 188, 188, 188, + 188, 188, 188, 188, 188, 188, 189, 189, 189, 189, + 189, 190, 190, 190, 190, 190, 191, 192, 193, 193, + + 194, 194, 194, 194, 194, 195, 195, 195, 195, 196, + 196, 197, 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 199, 199, 199, 199, + 199, 199, 199, 199, 200, 200, 200, 200, 200, 200, + 201, 201, 201, 201, 201, 202, 202, 202, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 204, 204, 205, 206, 207, 207, 208, 208, + 209, 210, 211, 211, 212, 212 } ; static yyconst int yy_ec[256] = @@ -439,248 +455,269 @@ static yyconst int yy_meta[44] = 3, 3, 3 } ; -static yyconst short int yy_base[531] = +static yyconst short int yy_base[581] = { 0, - 0, 0, 1140, 1141, 1141, 1141, 1135, 1124, 36, 40, + 0, 0, 1240, 1241, 1241, 1241, 1235, 1224, 36, 40, 44, 50, 56, 62, 0, 63, 66, 81, 89, 47, 100, 97, 76, 96, 111, 49, 113, 110, 68, 140, - 126, 171, 119, 118, 139, 133, 1133, 1141, 1122, 1141, - 0, 176, 184, 199, 204, 70, 209, 224, 229, 0, - 117, 130, 150, 72, 160, 151, 159, 123, 1121, 230, - 178, 31, 69, 168, 240, 95, 233, 165, 241, 243, - 242, 156, 244, 246, 187, 251, 253, 254, 211, 258, - 256, 263, 260, 265, 190, 267, 283, 1120, 271, 274, - 270, 285, 289, 290, 291, 292, 294, 295, 297, 299, - - 296, 308, 1119, 311, 300, 318, 320, 322, 323, 330, - 325, 328, 327, 337, 342, 216, 336, 345, 1118, 0, - 362, 366, 1117, 380, 397, 0, 1116, 370, 349, 1115, - 373, 1114, 355, 1113, 371, 372, 384, 1112, 392, 326, - 399, 398, 401, 402, 1111, 405, 404, 406, 411, 412, - 409, 413, 415, 422, 423, 425, 424, 426, 428, 429, - 435, 442, 374, 443, 444, 445, 446, 447, 1110, 1109, - 448, 449, 1108, 450, 1107, 1106, 476, 454, 455, 464, - 459, 488, 1105, 470, 1104, 490, 489, 460, 492, 1103, - 493, 494, 495, 496, 501, 502, 504, 507, 508, 512, - - 514, 517, 519, 520, 521, 518, 457, 522, 526, 530, - 539, 540, 541, 1102, 524, 1141, 550, 564, 568, 572, - 577, 578, 458, 579, 580, 1101, 1100, 1099, 581, 582, - 583, 584, 550, 585, 525, 586, 589, 551, 590, 587, - 607, 591, 594, 1098, 592, 1097, 1096, 603, 611, 610, - 593, 613, 617, 620, 621, 622, 1095, 1094, 623, 625, - 1093, 624, 626, 0, 627, 1092, 629, 638, 630, 643, - 644, 646, 628, 647, 654, 1091, 656, 661, 1090, 660, - 658, 1089, 1088, 662, 1087, 1086, 659, 664, 672, 675, - 676, 1085, 677, 678, 679, 681, 1084, 682, 1083, 684, - - 683, 690, 1082, 692, 695, 1081, 700, 704, 710, 711, - 691, 713, 701, 702, 714, 715, 718, 722, 724, 1080, - 726, 1079, 725, 727, 728, 729, 730, 736, 1078, 737, - 740, 743, 746, 748, 751, 1077, 735, 738, 1076, 1075, - 1074, 1073, 1072, 1071, 1070, 756, 758, 1069, 762, 759, - 763, 1068, 1067, 1066, 764, 766, 767, 765, 769, 1065, - 770, 776, 778, 777, 779, 1064, 781, 1063, 784, 785, - 786, 790, 791, 797, 798, 1062, 1061, 1060, 802, 795, - 1059, 803, 1058, 808, 811, 804, 1057, 805, 1056, 1055, - 1054, 1053, 810, 821, 1052, 823, 824, 1051, 1050, 1049, - - 822, 825, 1048, 1047, 1046, 1045, 826, 827, 828, 829, - 830, 833, 1044, 839, 1043, 1042, 840, 843, 844, 845, - 846, 850, 848, 851, 852, 853, 854, 1041, 858, 863, - 868, 869, 871, 875, 877, 878, 879, 1040, 881, 885, - 886, 882, 1037, 887, 889, 888, 894, 1028, 1026, 897, - 895, 892, 900, 907, 1025, 912, 916, 914, 1024, 917, - 1023, 1021, 918, 920, 922, 925, 926, 924, 928, 931, - 933, 932, 934, 936, 938, 1020, 941, 944, 937, 948, - 949, 950, 952, 1019, 957, 961, 962, 963, 964, 1018, - 965, 966, 967, 968, 1013, 969, 972, 1010, 973, 976, - - 982, 984, 990, 991, 992, 993, 994, 996, 997, 998, - 999, 1006, 1000, 896, 893, 633, 1005, 632, 1007, 385, - 354, 353, 1008, 301, 1141, 1043, 1045, 226, 1049, 166 + 126, 171, 120, 130, 124, 141, 1233, 1241, 1222, 1241, + 0, 159, 176, 199, 204, 70, 209, 224, 229, 0, + 137, 165, 143, 72, 169, 159, 230, 215, 1221, 168, + 182, 31, 69, 187, 240, 191, 242, 243, 244, 248, + 246, 245, 251, 254, 256, 249, 260, 262, 264, 211, + 273, 274, 270, 280, 275, 284, 285, 288, 292, 1220, + 293, 294, 298, 300, 301, 276, 302, 310, 311, 313, + + 305, 309, 312, 330, 331, 1219, 334, 320, 322, 338, + 340, 324, 341, 346, 348, 361, 356, 359, 162, 353, + 368, 1218, 0, 383, 387, 1217, 401, 418, 0, 1216, + 376, 370, 1215, 393, 373, 1214, 392, 1213, 406, 407, + 408, 403, 1212, 419, 95, 420, 372, 409, 421, 1211, + 425, 431, 428, 430, 433, 435, 432, 440, 443, 444, + 445, 451, 447, 446, 449, 450, 453, 461, 468, 458, + 469, 470, 473, 474, 475, 480, 1210, 1209, 481, 482, + 1208, 483, 485, 1207, 1206, 513, 491, 488, 494, 489, + 524, 503, 1205, 486, 1204, 487, 525, 527, 250, 528, + + 1203, 506, 531, 532, 536, 542, 538, 530, 537, 540, + 548, 544, 556, 550, 560, 557, 375, 554, 568, 558, + 571, 493, 576, 564, 582, 1202, 574, 552, 1241, 591, + 605, 609, 613, 618, 619, 577, 620, 1201, 621, 591, + 1200, 1199, 1198, 622, 623, 624, 625, 626, 628, 627, + 632, 630, 634, 633, 635, 644, 642, 643, 1197, 653, + 655, 657, 658, 1196, 1195, 659, 660, 661, 662, 663, + 667, 583, 671, 669, 673, 1194, 1193, 1192, 672, 677, + 1191, 675, 666, 680, 0, 691, 1190, 693, 694, 695, + 696, 702, 703, 1189, 697, 585, 704, 707, 1188, 709, + + 714, 1187, 722, 708, 1186, 726, 1185, 727, 1184, 1183, + 724, 728, 730, 716, 732, 735, 1182, 738, 741, 742, + 743, 1181, 744, 1180, 746, 745, 1179, 751, 1178, 755, + 757, 1177, 751, 754, 764, 771, 772, 763, 499, 766, + 774, 779, 775, 776, 780, 782, 1176, 783, 1175, 1174, + 781, 787, 786, 795, 791, 796, 798, 801, 805, 802, + 1173, 808, 807, 810, 813, 814, 819, 820, 1172, 809, + 815, 1171, 1170, 1169, 1168, 1167, 1166, 1165, 826, 829, + 830, 1164, 831, 832, 835, 1163, 1162, 834, 1161, 1160, + 836, 840, 837, 842, 846, 1159, 848, 850, 851, 852, + + 860, 1158, 854, 858, 1157, 861, 862, 864, 870, 866, + 868, 872, 1156, 1155, 1154, 880, 873, 1153, 1152, 1151, + 876, 882, 1150, 891, 893, 889, 874, 1149, 899, 1148, + 1147, 1146, 1145, 887, 895, 901, 1144, 904, 905, 1143, + 1142, 1141, 1140, 1139, 903, 907, 1138, 1137, 1136, 1135, + 909, 910, 914, 917, 911, 1134, 920, 1133, 921, 1132, + 1131, 923, 925, 926, 927, 929, 1130, 931, 933, 934, + 936, 935, 945, 937, 941, 1129, 947, 948, 953, 955, + 961, 962, 966, 963, 965, 1128, 967, 969, 971, 968, + 1127, 974, 978, 975, 979, 1126, 1123, 1113, 980, 1112, + + 981, 996, 982, 999, 1111, 1000, 1001, 1002, 1109, 987, + 1108, 1107, 1004, 1008, 1011, 1013, 1012, 1014, 1016, 1019, + 1020, 1021, 1022, 1024, 1025, 1104, 1026, 1029, 1031, 1032, + 1035, 1037, 1038, 1101, 1041, 1047, 1048, 1049, 1051, 1100, + 1053, 1052, 1054, 1057, 1098, 1058, 1059, 1096, 1065, 1071, + 1060, 1069, 1072, 1077, 1079, 1082, 1081, 1083, 1084, 1085, + 1087, 984, 1088, 983, 710, 668, 1092, 664, 1097, 593, + 345, 214, 1094, 213, 1241, 1129, 1131, 187, 1135, 138 } ; -static yyconst short int yy_def[531] = +static yyconst short int yy_def[581] = { 0, - 525, 1, 525, 525, 525, 525, 526, 527, 528, 525, - 527, 527, 527, 527, 529, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 526, 525, 527, 525, - 530, 530, 525, 525, 527, 527, 527, 527, 527, 529, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 525, 530, - 530, 525, 527, 527, 527, 49, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 49, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 525, 525, 525, 525, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 177, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - - 527, 525, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 0, 525, 525, 525, 525, 525 + 575, 1, 575, 575, 575, 575, 576, 577, 578, 575, + 577, 577, 577, 577, 579, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 576, 575, 577, 575, + 580, 580, 575, 575, 577, 577, 577, 577, 577, 579, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 575, 580, 580, 575, 577, 577, 577, 49, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 49, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 575, 575, + 575, 575, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 186, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 575, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 577, 0, 575, 575, 575, 575, 575 } ; -static yyconst short int yy_nxt[1185] = +static yyconst short int yy_nxt[1285] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 4, 15, 8, 8, 8, 16, 17, 18, 19, 20, 21, 22, 8, 23, 8, 24, 25, 26, 27, 28, 8, 29, 30, 31, 32, 33, 34, 35, 8, 36, 42, 40, 43, 43, 43, 43, 44, - 44, 44, 44, 45, 45, 45, 45, 40, 46, 139, - 40, 140, 40, 40, 47, 48, 48, 48, 48, 40, - 47, 48, 48, 48, 48, 40, 40, 69, 123, 40, - 85, 40, 40, 40, 51, 40, 86, 70, 56, 40, - 91, 52, 57, 53, 40, 54, 49, 58, 55, 60, - - 59, 61, 40, 141, 131, 77, 78, 64, 40, 40, - 40, 65, 62, 40, 79, 66, 63, 67, 71, 75, - 68, 72, 80, 40, 40, 76, 40, 81, 73, 82, - 40, 40, 40, 145, 74, 89, 40, 113, 127, 40, - 115, 90, 83, 40, 102, 87, 40, 88, 84, 92, - 114, 116, 40, 40, 135, 118, 128, 103, 129, 93, - 104, 94, 95, 40, 40, 96, 97, 105, 120, 40, - 117, 130, 40, 40, 98, 133, 99, 100, 40, 101, - 92, 40, 153, 134, 40, 121, 121, 121, 121, 132, - 106, 40, 107, 43, 43, 43, 43, 108, 138, 109, - - 40, 110, 147, 40, 142, 111, 112, 122, 44, 44, - 44, 44, 47, 45, 45, 45, 45, 40, 124, 124, - 124, 124, 40, 156, 40, 125, 170, 213, 41, 40, - 162, 125, 47, 48, 48, 48, 48, 40, 126, 126, - 126, 126, 40, 40, 126, 126, 40, 126, 126, 126, - 126, 126, 126, 40, 40, 40, 40, 40, 136, 40, - 143, 146, 148, 149, 40, 137, 40, 40, 155, 40, - 151, 40, 144, 40, 165, 154, 40, 152, 40, 150, - 40, 168, 157, 40, 40, 158, 166, 40, 163, 159, - 160, 167, 161, 169, 164, 171, 40, 173, 40, 175, - - 174, 172, 40, 40, 40, 40, 176, 40, 40, 40, - 40, 180, 40, 40, 40, 187, 179, 188, 190, 181, - 183, 40, 191, 184, 40, 177, 185, 182, 189, 186, - 178, 40, 196, 40, 192, 40, 40, 194, 40, 40, - 40, 40, 193, 40, 207, 208, 198, 205, 195, 40, - 40, 201, 199, 206, 200, 40, 202, 209, 40, 197, - 212, 230, 40, 210, 203, 211, 40, 40, 40, 204, - 214, 121, 121, 121, 121, 217, 217, 217, 217, 215, - 223, 225, 218, 40, 40, 40, 40, 40, 218, 124, - 124, 124, 124, 40, 222, 224, 125, 40, 40, 226, - - 227, 255, 125, 219, 220, 40, 221, 221, 221, 221, - 40, 40, 40, 229, 40, 40, 232, 40, 40, 40, - 228, 231, 40, 237, 40, 40, 40, 235, 40, 233, - 234, 236, 238, 239, 240, 40, 40, 40, 40, 40, - 245, 40, 40, 249, 242, 246, 241, 248, 40, 243, - 251, 252, 247, 244, 250, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 254, 257, 253, 40, 40, 258, - 40, 40, 40, 40, 259, 294, 261, 40, 304, 256, - 263, 268, 262, 40, 260, 264, 264, 264, 264, 276, - 265, 264, 264, 266, 264, 264, 264, 264, 264, 264, - - 267, 40, 40, 40, 273, 40, 40, 40, 40, 40, - 269, 275, 270, 274, 40, 40, 271, 40, 272, 280, - 40, 40, 279, 282, 283, 40, 277, 40, 281, 278, - 40, 40, 40, 40, 40, 40, 288, 40, 40, 40, - 284, 290, 287, 40, 286, 285, 291, 289, 296, 293, - 292, 297, 40, 40, 40, 301, 295, 298, 300, 217, - 217, 217, 217, 40, 40, 313, 218, 299, 311, 316, - 219, 219, 218, 302, 302, 302, 302, 302, 302, 302, - 302, 221, 221, 221, 221, 40, 221, 221, 221, 221, + 44, 44, 44, 45, 45, 45, 45, 40, 46, 144, + 40, 145, 40, 40, 47, 48, 48, 48, 48, 40, + 47, 48, 48, 48, 48, 40, 40, 69, 126, 40, + 87, 40, 40, 40, 51, 40, 88, 70, 56, 40, + 94, 52, 57, 53, 40, 54, 49, 58, 55, 60, + + 59, 61, 40, 146, 134, 78, 79, 64, 40, 40, + 40, 65, 62, 40, 80, 66, 63, 67, 71, 76, + 68, 72, 81, 40, 40, 77, 40, 82, 73, 84, + 245, 83, 74, 40, 75, 91, 119, 40, 116, 40, + 123, 92, 85, 40, 105, 89, 93, 90, 86, 95, + 40, 117, 118, 40, 40, 120, 40, 106, 130, 96, + 107, 97, 98, 121, 133, 99, 100, 108, 124, 124, + 124, 124, 40, 225, 101, 40, 102, 103, 40, 104, + 95, 40, 40, 137, 40, 43, 43, 43, 43, 41, + 109, 131, 110, 132, 135, 40, 141, 111, 136, 112, + + 40, 113, 143, 142, 40, 114, 115, 125, 44, 44, + 44, 44, 47, 45, 45, 45, 45, 40, 127, 127, + 127, 127, 40, 147, 40, 128, 40, 40, 40, 150, + 169, 128, 47, 48, 48, 48, 48, 40, 129, 129, + 129, 129, 40, 40, 129, 129, 140, 129, 129, 129, + 129, 129, 129, 40, 138, 40, 40, 40, 40, 40, + 148, 40, 40, 40, 40, 153, 139, 40, 154, 40, + 151, 158, 149, 40, 156, 40, 160, 40, 162, 299, + 152, 157, 159, 40, 155, 163, 40, 40, 40, 40, + 161, 164, 172, 40, 165, 174, 176, 40, 40, 166, + + 167, 40, 168, 170, 173, 40, 40, 40, 175, 171, + 180, 40, 177, 40, 40, 40, 179, 187, 40, 181, + 182, 178, 40, 40, 40, 40, 40, 199, 188, 184, + 189, 201, 183, 40, 197, 40, 185, 40, 190, 193, + 200, 186, 194, 40, 40, 195, 191, 40, 196, 198, + 192, 40, 207, 40, 40, 212, 202, 203, 40, 40, + 205, 40, 213, 208, 209, 204, 40, 214, 217, 40, + 210, 206, 40, 218, 40, 215, 211, 224, 219, 220, + 216, 40, 222, 40, 223, 40, 40, 226, 40, 40, + 247, 221, 124, 124, 124, 124, 230, 230, 230, 230, + + 235, 236, 227, 231, 317, 40, 40, 238, 228, 231, + 127, 127, 127, 127, 40, 237, 40, 128, 239, 40, + 40, 40, 40, 128, 232, 233, 240, 234, 234, 234, + 234, 40, 40, 40, 40, 241, 242, 248, 40, 243, + 244, 40, 246, 40, 40, 40, 40, 250, 40, 249, + 252, 251, 254, 40, 253, 255, 40, 40, 40, 40, + 40, 260, 40, 40, 40, 267, 40, 256, 258, 266, + 257, 40, 269, 264, 40, 270, 262, 268, 259, 263, + 265, 40, 40, 40, 261, 274, 40, 40, 40, 271, + 273, 276, 272, 40, 40, 40, 40, 277, 40, 40, + + 40, 40, 40, 279, 40, 275, 40, 40, 278, 281, + 296, 289, 40, 283, 322, 282, 40, 280, 410, 40, + 295, 284, 285, 285, 285, 285, 287, 286, 285, 285, + 288, 285, 285, 285, 285, 285, 285, 40, 40, 294, + 40, 40, 301, 40, 40, 40, 290, 297, 291, 40, + 40, 40, 292, 40, 293, 40, 303, 40, 298, 302, + 307, 40, 300, 40, 305, 40, 308, 40, 304, 40, + 40, 40, 306, 40, 312, 309, 310, 40, 313, 311, + 314, 40, 315, 316, 40, 318, 319, 40, 327, 40, + 40, 324, 320, 321, 323, 40, 40, 330, 40, 325, + + 230, 230, 230, 230, 40, 326, 40, 231, 379, 333, + 360, 232, 232, 231, 328, 328, 328, 328, 328, 328, + 328, 328, 234, 234, 234, 234, 40, 234, 234, 234, + 234, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 334, 40, 338, 40, 40, 40, 40, 329, + 331, 332, 343, 337, 339, 40, 40, 40, 342, 335, + 336, 341, 346, 348, 347, 344, 40, 340, 40, 345, + 40, 40, 40, 40, 40, 40, 40, 40, 355, 40, + 40, 40, 40, 356, 40, 40, 40, 354, 40, 349, + 40, 350, 351, 40, 352, 353, 357, 358, 359, 361, + + 362, 363, 367, 364, 40, 365, 40, 40, 40, 40, + 40, 368, 366, 369, 371, 40, 40, 40, 373, 370, + 40, 40, 40, 40, 375, 377, 380, 40, 372, 40, + 381, 382, 374, 378, 383, 40, 385, 40, 376, 40, + 40, 40, 391, 40, 384, 40, 386, 388, 40, 387, + 392, 40, 389, 390, 40, 40, 40, 40, 40, 40, + 328, 328, 328, 328, 40, 393, 396, 40, 40, 399, + 40, 401, 394, 402, 405, 395, 40, 40, 403, 40, + 398, 400, 406, 397, 40, 40, 404, 40, 40, 40, + 408, 407, 40, 40, 40, 40, 40, 409, 411, 40, + + 40, 413, 417, 418, 40, 414, 412, 419, 40, 40, + 416, 40, 415, 420, 40, 40, 421, 422, 40, 423, + 40, 40, 40, 40, 428, 424, 40, 40, 40, 430, + 431, 426, 40, 40, 425, 432, 433, 427, 429, 40, + 436, 434, 40, 40, 40, 40, 435, 40, 40, 40, + 40, 437, 439, 40, 438, 40, 441, 443, 447, 40, + 446, 40, 440, 40, 40, 40, 444, 40, 442, 452, + 449, 40, 445, 40, 40, 40, 451, 40, 448, 40, + 455, 40, 458, 40, 450, 40, 40, 40, 453, 40, + 454, 457, 460, 40, 456, 40, 467, 464, 465, 462, + + 40, 461, 40, 463, 40, 459, 40, 471, 40, 466, + 472, 468, 40, 469, 40, 470, 40, 40, 40, 473, + 40, 474, 40, 40, 40, 475, 477, 40, 478, 479, + 40, 476, 480, 40, 40, 483, 40, 481, 40, 40, + 40, 485, 40, 484, 40, 482, 40, 40, 40, 40, + 40, 492, 487, 493, 40, 491, 486, 488, 40, 489, + 40, 40, 495, 494, 496, 490, 40, 498, 40, 497, + 502, 503, 499, 504, 40, 40, 40, 500, 40, 40, + 40, 40, 40, 505, 40, 501, 507, 40, 40, 509, + 513, 40, 40, 40, 40, 40, 40, 40, 506, 508, + + 40, 517, 514, 519, 510, 511, 518, 512, 515, 40, + 521, 516, 40, 40, 40, 40, 520, 40, 522, 524, + 523, 40, 527, 526, 40, 40, 40, 40, 525, 40, + 528, 530, 40, 40, 40, 40, 533, 40, 40, 40, + 537, 531, 40, 539, 40, 40, 535, 529, 40, 536, + 40, 40, 538, 540, 40, 534, 532, 544, 541, 545, + 40, 40, 40, 542, 40, 40, 40, 40, 543, 548, + 40, 40, 40, 40, 546, 552, 549, 550, 40, 551, + 554, 557, 40, 547, 40, 40, 560, 555, 553, 556, + 40, 559, 40, 558, 40, 40, 40, 40, 40, 561, + + 40, 40, 566, 567, 568, 40, 562, 40, 563, 40, + 40, 40, 572, 40, 40, 564, 565, 40, 571, 573, + 40, 40, 40, 570, 40, 40, 40, 569, 574, 37, + 37, 37, 37, 39, 39, 50, 40, 50, 50, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - - 40, 307, 40, 40, 40, 40, 40, 40, 303, 305, - 306, 312, 310, 320, 321, 314, 40, 315, 308, 309, - 40, 318, 317, 40, 40, 319, 40, 326, 322, 324, - 40, 323, 325, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 328, 40, 40, 327, 329, 336, - 331, 40, 330, 333, 332, 337, 40, 40, 338, 40, - 40, 334, 335, 339, 345, 340, 342, 40, 344, 40, - 346, 40, 40, 40, 40, 40, 347, 40, 348, 341, - 343, 349, 350, 353, 352, 40, 351, 354, 40, 40, - 40, 40, 40, 356, 40, 40, 40, 40, 355, 302, - - 302, 302, 302, 360, 40, 40, 357, 363, 40, 365, - 366, 358, 359, 40, 40, 40, 367, 40, 362, 364, - 368, 361, 369, 40, 40, 372, 40, 40, 40, 371, - 370, 40, 373, 374, 375, 40, 376, 40, 40, 40, - 40, 40, 40, 40, 380, 377, 381, 382, 40, 40, - 40, 40, 379, 40, 378, 383, 40, 384, 387, 40, - 386, 40, 389, 390, 40, 385, 394, 388, 391, 40, - 392, 40, 40, 393, 395, 40, 40, 40, 40, 40, - 40, 397, 40, 40, 396, 400, 402, 398, 403, 40, - 40, 40, 40, 405, 40, 399, 408, 40, 40, 40, - - 401, 404, 407, 40, 40, 413, 406, 411, 40, 410, - 40, 40, 415, 409, 412, 40, 40, 40, 40, 419, - 420, 40, 425, 40, 40, 426, 416, 414, 417, 418, - 423, 421, 422, 424, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 427, 429, 40, 430, 431, 435, - 432, 428, 40, 40, 433, 436, 40, 40, 40, 40, - 437, 40, 434, 40, 40, 40, 40, 40, 444, 438, - 439, 40, 445, 443, 440, 449, 40, 441, 446, 447, - 448, 40, 40, 442, 40, 452, 453, 454, 40, 450, - 40, 40, 40, 455, 40, 40, 451, 457, 40, 40, - - 40, 40, 40, 459, 463, 40, 40, 40, 40, 40, - 40, 456, 470, 40, 458, 464, 467, 469, 460, 465, - 40, 461, 462, 468, 466, 40, 472, 40, 471, 40, - 40, 40, 473, 40, 474, 40, 477, 40, 40, 40, - 475, 40, 478, 480, 40, 40, 40, 40, 483, 40, - 40, 40, 487, 476, 40, 481, 489, 40, 479, 485, - 486, 40, 40, 40, 488, 40, 482, 484, 490, 492, - 40, 494, 495, 491, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 498, 493, 40, 40, 502, 496, 40, - 499, 500, 501, 504, 507, 40, 509, 40, 505, 497, - - 506, 508, 503, 40, 40, 40, 40, 40, 510, 40, - 40, 40, 40, 40, 511, 516, 517, 518, 40, 40, - 40, 40, 513, 40, 512, 522, 40, 515, 514, 523, - 521, 40, 40, 40, 40, 520, 40, 40, 40, 40, - 519, 40, 524, 37, 37, 37, 37, 39, 39, 50, - 40, 50, 50, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, @@ -689,15 +726,15 @@ static yyconst short int yy_nxt[1185] = 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 216, 40, 40, 40, 40, 119, 40, 38, 525, - 3, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525 + 40, 229, 40, 40, 40, 40, 122, 40, 38, 575, + 3, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575 } ; -static yyconst short int yy_chk[1185] = +static yyconst short int yy_chk[1285] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -710,125 +747,136 @@ static yyconst short int yy_chk[1185] = 26, 29, 63, 46, 16, 54, 26, 20, 17, 23, 29, 16, 17, 16, 18, 16, 13, 17, 16, 18, - 17, 18, 19, 63, 54, 23, 23, 19, 66, 24, + 17, 18, 19, 63, 54, 23, 23, 19, 145, 24, 22, 19, 18, 21, 24, 19, 18, 19, 21, 22, 19, 21, 24, 28, 25, 22, 27, 24, 21, 25, - 51, 34, 33, 66, 21, 28, 58, 33, 51, 31, - 34, 28, 25, 52, 31, 27, 36, 27, 25, 30, - 33, 35, 35, 30, 58, 36, 52, 31, 52, 30, - 31, 30, 30, 53, 56, 30, 30, 31, 530, 72, - 35, 53, 57, 55, 30, 56, 30, 30, 68, 30, - 32, 64, 72, 57, 32, 42, 42, 42, 42, 55, - 32, 61, 32, 43, 43, 43, 43, 32, 61, 32, - - 75, 32, 68, 85, 64, 32, 32, 44, 44, 44, + 145, 24, 21, 33, 21, 28, 35, 35, 33, 31, + 580, 28, 25, 34, 31, 27, 28, 27, 25, 30, + 51, 33, 34, 30, 36, 35, 53, 31, 51, 30, + 31, 30, 30, 36, 53, 30, 30, 31, 42, 42, + 42, 42, 56, 119, 30, 119, 30, 30, 52, 30, + 32, 60, 55, 56, 32, 43, 43, 43, 43, 578, + 32, 52, 32, 52, 55, 61, 60, 32, 55, 32, + + 64, 32, 61, 60, 66, 32, 32, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 47, 47, - 47, 47, 47, 75, 79, 47, 85, 116, 528, 116, - 79, 47, 48, 48, 48, 48, 48, 48, 49, 49, - 49, 49, 49, 60, 49, 49, 67, 49, 49, 49, - 49, 49, 49, 65, 69, 71, 70, 73, 60, 74, - 65, 67, 69, 70, 76, 60, 77, 78, 74, 81, - 71, 80, 65, 83, 81, 73, 82, 71, 84, 70, - 86, 83, 76, 91, 89, 77, 81, 90, 80, 78, - 78, 82, 78, 84, 80, 86, 87, 89, 92, 91, - - 90, 87, 93, 94, 95, 96, 91, 97, 98, 101, - 99, 95, 100, 105, 524, 97, 94, 98, 100, 95, - 96, 102, 101, 96, 104, 92, 96, 95, 99, 96, - 93, 106, 105, 107, 102, 108, 109, 104, 111, 140, - 113, 112, 102, 110, 113, 113, 107, 111, 104, 117, - 114, 110, 108, 112, 109, 115, 110, 113, 118, 106, - 115, 140, 129, 114, 110, 114, 522, 521, 133, 110, - 117, 121, 121, 121, 121, 122, 122, 122, 122, 118, - 129, 133, 122, 128, 135, 136, 131, 163, 122, 124, - 124, 124, 124, 124, 128, 131, 124, 137, 520, 135, - - 136, 163, 124, 125, 125, 139, 125, 125, 125, 125, - 125, 142, 141, 139, 143, 144, 142, 147, 146, 148, - 137, 141, 151, 147, 149, 150, 152, 146, 153, 143, - 144, 146, 148, 149, 150, 154, 155, 157, 156, 158, - 154, 159, 160, 157, 151, 155, 150, 156, 161, 152, - 159, 160, 155, 153, 158, 162, 164, 165, 166, 167, - 168, 171, 172, 174, 162, 165, 161, 178, 179, 166, - 207, 223, 181, 188, 167, 207, 171, 180, 223, 164, - 174, 181, 172, 184, 168, 177, 177, 177, 177, 188, - 178, 177, 177, 179, 177, 177, 177, 177, 177, 177, - - 180, 182, 187, 186, 184, 189, 191, 192, 193, 194, - 182, 187, 182, 186, 195, 196, 182, 197, 182, 193, - 198, 199, 192, 195, 196, 200, 189, 201, 194, 191, - 202, 206, 203, 204, 205, 208, 201, 215, 235, 209, - 197, 203, 200, 210, 199, 198, 204, 202, 209, 206, - 205, 210, 211, 212, 213, 215, 208, 211, 213, 217, - 217, 217, 217, 233, 238, 235, 217, 212, 233, 238, - 218, 218, 217, 218, 218, 218, 218, 219, 219, 219, - 219, 220, 220, 220, 220, 220, 221, 221, 221, 221, - 221, 222, 224, 225, 229, 230, 231, 232, 234, 236, - - 240, 229, 237, 239, 242, 245, 251, 243, 222, 224, - 225, 234, 232, 242, 243, 236, 248, 237, 230, 231, - 241, 240, 239, 250, 249, 241, 252, 251, 245, 249, - 253, 248, 250, 254, 255, 256, 259, 262, 260, 263, - 265, 273, 267, 269, 253, 518, 516, 252, 254, 265, - 256, 268, 255, 260, 259, 267, 270, 271, 268, 272, - 274, 262, 263, 269, 273, 270, 271, 275, 272, 277, - 274, 281, 287, 280, 278, 284, 275, 288, 277, 270, - 271, 278, 280, 287, 284, 289, 281, 288, 290, 291, - 293, 294, 295, 290, 296, 298, 301, 300, 289, 302, - - 302, 302, 302, 295, 311, 304, 291, 300, 305, 301, - 304, 293, 294, 307, 313, 314, 305, 308, 298, 300, - 307, 296, 308, 309, 310, 311, 312, 315, 316, 310, - 309, 317, 312, 313, 314, 318, 315, 319, 323, 321, - 324, 325, 326, 327, 319, 316, 321, 323, 337, 328, - 330, 338, 318, 331, 317, 324, 332, 325, 328, 333, - 327, 334, 331, 332, 335, 326, 337, 330, 333, 346, - 334, 347, 350, 335, 338, 349, 351, 355, 358, 356, - 357, 347, 359, 361, 346, 351, 356, 349, 357, 362, - 364, 363, 365, 359, 367, 350, 363, 369, 370, 371, - - 355, 358, 362, 372, 373, 370, 361, 367, 380, 365, - 374, 375, 372, 364, 369, 379, 382, 386, 388, 379, - 379, 384, 386, 393, 385, 388, 373, 371, 374, 375, - 384, 380, 382, 385, 394, 401, 396, 397, 402, 407, - 408, 409, 410, 411, 393, 396, 412, 397, 401, 409, - 402, 394, 414, 417, 407, 410, 418, 419, 420, 421, - 411, 423, 408, 422, 424, 425, 426, 427, 421, 412, - 414, 429, 422, 420, 417, 426, 430, 418, 423, 424, - 425, 431, 432, 419, 433, 430, 431, 432, 434, 427, - 435, 436, 437, 433, 439, 442, 429, 435, 440, 441, - - 444, 446, 445, 437, 442, 452, 515, 447, 451, 514, - 450, 434, 452, 453, 436, 444, 447, 451, 439, 445, - 454, 440, 441, 450, 446, 456, 454, 458, 453, 457, - 460, 463, 456, 464, 457, 465, 463, 468, 466, 467, - 458, 469, 464, 466, 470, 472, 471, 473, 469, 474, - 479, 475, 473, 460, 477, 467, 475, 478, 465, 471, - 472, 480, 481, 482, 474, 483, 468, 470, 477, 479, - 485, 481, 482, 478, 486, 487, 488, 489, 491, 492, - 493, 494, 496, 486, 480, 497, 499, 491, 483, 500, - 487, 488, 489, 493, 497, 501, 500, 502, 494, 485, - - 496, 499, 492, 503, 504, 505, 506, 507, 501, 508, - 509, 510, 511, 513, 502, 507, 508, 509, 517, 512, - 519, 523, 504, 498, 503, 517, 495, 506, 505, 519, - 513, 490, 484, 476, 462, 511, 461, 459, 455, 449, - 510, 448, 523, 526, 526, 526, 526, 527, 527, 529, - 443, 529, 529, 438, 428, 416, 415, 413, 406, 405, - 404, 403, 400, 399, 398, 395, 392, 391, 390, 389, - 387, 383, 381, 378, 377, 376, 368, 366, 360, 354, - 353, 352, 348, 345, 344, 343, 342, 341, 340, 339, - 336, 329, 322, 320, 306, 303, 299, 297, 292, 286, - - 285, 283, 282, 279, 276, 266, 261, 258, 257, 247, - 246, 244, 228, 227, 226, 214, 190, 185, 183, 176, - 175, 173, 170, 169, 145, 138, 134, 132, 130, 127, - 123, 119, 103, 88, 59, 39, 37, 8, 7, 3, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525 + 47, 47, 47, 64, 80, 47, 574, 572, 58, 66, + 80, 47, 48, 48, 48, 48, 48, 48, 49, 49, + 49, 49, 49, 57, 49, 49, 58, 49, 49, 49, + 49, 49, 49, 65, 57, 67, 68, 69, 72, 71, + 65, 70, 76, 199, 73, 69, 57, 74, 70, 75, + 67, 72, 65, 77, 71, 78, 74, 79, 75, 199, + 68, 71, 73, 83, 70, 76, 81, 82, 85, 96, + 74, 77, 82, 84, 78, 83, 85, 86, 87, 79, + + 79, 88, 79, 81, 82, 89, 91, 92, 84, 81, + 89, 93, 86, 94, 95, 97, 88, 96, 101, 91, + 92, 87, 102, 98, 99, 103, 100, 101, 97, 94, + 98, 103, 93, 108, 100, 109, 94, 112, 98, 99, + 102, 95, 99, 104, 105, 99, 98, 107, 99, 100, + 98, 110, 108, 111, 113, 112, 104, 105, 571, 114, + 107, 115, 113, 109, 110, 105, 120, 113, 114, 117, + 111, 107, 118, 115, 116, 113, 111, 118, 116, 116, + 113, 121, 117, 132, 117, 147, 135, 120, 217, 131, + 147, 116, 124, 124, 124, 124, 125, 125, 125, 125, + + 131, 132, 121, 125, 217, 137, 134, 135, 121, 125, + 127, 127, 127, 127, 127, 134, 142, 127, 137, 139, + 140, 141, 148, 127, 128, 128, 139, 128, 128, 128, + 128, 128, 144, 146, 149, 140, 141, 148, 151, 142, + 144, 153, 146, 154, 152, 157, 155, 151, 156, 149, + 152, 151, 154, 158, 153, 155, 159, 160, 161, 164, + 163, 159, 165, 166, 162, 164, 167, 155, 157, 163, + 156, 170, 166, 162, 168, 167, 161, 165, 158, 161, + 162, 169, 171, 172, 160, 170, 173, 174, 175, 167, + 169, 172, 168, 176, 179, 180, 182, 173, 183, 194, + + 196, 188, 190, 175, 187, 171, 222, 189, 174, 179, + 196, 190, 339, 182, 222, 180, 192, 176, 339, 202, + 194, 183, 186, 186, 186, 186, 188, 187, 186, 186, + 189, 186, 186, 186, 186, 186, 186, 191, 197, 192, + 198, 200, 202, 208, 203, 204, 191, 197, 191, 205, + 209, 207, 191, 210, 191, 206, 204, 212, 198, 203, + 207, 211, 200, 214, 206, 228, 208, 218, 205, 213, + 216, 220, 206, 215, 212, 209, 210, 224, 213, 211, + 214, 219, 215, 216, 221, 218, 219, 227, 228, 223, + 236, 224, 220, 221, 223, 225, 272, 236, 296, 225, + + 230, 230, 230, 230, 240, 227, 570, 230, 296, 240, + 272, 231, 231, 230, 231, 231, 231, 231, 232, 232, + 232, 232, 233, 233, 233, 233, 233, 234, 234, 234, + 234, 234, 235, 237, 239, 244, 245, 246, 247, 248, + 250, 249, 244, 252, 248, 251, 254, 253, 255, 235, + 237, 239, 253, 247, 249, 257, 258, 256, 252, 245, + 246, 251, 256, 258, 257, 254, 260, 250, 261, 255, + 262, 263, 266, 267, 268, 269, 270, 568, 267, 283, + 271, 566, 274, 268, 273, 279, 275, 266, 282, 260, + 280, 261, 262, 284, 262, 263, 269, 270, 271, 273, + + 274, 275, 283, 279, 286, 280, 288, 289, 290, 291, + 295, 284, 282, 286, 289, 292, 293, 297, 291, 288, + 298, 304, 300, 565, 292, 293, 297, 301, 290, 314, + 298, 300, 291, 295, 301, 303, 304, 311, 292, 306, + 308, 312, 314, 313, 303, 315, 306, 311, 316, 308, + 315, 318, 312, 313, 319, 320, 321, 323, 326, 325, + 328, 328, 328, 328, 333, 316, 320, 334, 330, 325, + 331, 326, 318, 330, 334, 319, 338, 335, 331, 340, + 323, 325, 335, 321, 336, 337, 333, 341, 343, 344, + 337, 336, 342, 345, 351, 346, 348, 338, 340, 353, + + 352, 342, 346, 348, 355, 343, 341, 351, 354, 356, + 345, 357, 344, 352, 358, 360, 353, 354, 359, 355, + 363, 362, 370, 364, 360, 356, 365, 366, 371, 363, + 364, 358, 367, 368, 357, 365, 366, 359, 362, 379, + 370, 367, 380, 381, 383, 384, 368, 388, 385, 391, + 393, 371, 380, 392, 379, 394, 383, 385, 393, 395, + 392, 397, 381, 398, 399, 400, 388, 403, 384, 399, + 395, 404, 391, 401, 406, 407, 398, 408, 394, 410, + 403, 411, 407, 409, 397, 412, 417, 427, 400, 421, + 401, 406, 409, 416, 404, 422, 421, 416, 416, 411, + + 434, 410, 426, 412, 424, 408, 425, 426, 435, 417, + 427, 422, 429, 424, 436, 425, 445, 438, 439, 429, + 446, 434, 451, 452, 455, 435, 438, 453, 439, 445, + 454, 436, 446, 457, 459, 453, 462, 451, 463, 464, + 465, 455, 466, 454, 468, 452, 469, 470, 472, 471, + 474, 466, 459, 468, 475, 465, 457, 462, 473, 463, + 477, 478, 470, 469, 471, 464, 479, 473, 480, 472, + 478, 479, 474, 480, 481, 482, 484, 475, 485, 483, + 487, 490, 488, 481, 489, 477, 483, 492, 494, 485, + 490, 493, 495, 499, 501, 503, 564, 562, 482, 484, + + 510, 495, 492, 501, 487, 488, 499, 489, 493, 502, + 503, 494, 504, 506, 507, 508, 502, 513, 504, 507, + 506, 514, 513, 510, 515, 517, 516, 518, 508, 519, + 514, 516, 520, 521, 522, 523, 519, 524, 525, 527, + 523, 517, 528, 525, 529, 530, 521, 515, 531, 522, + 532, 533, 524, 527, 535, 520, 518, 531, 528, 532, + 536, 537, 538, 529, 539, 542, 541, 543, 530, 536, + 544, 546, 547, 551, 533, 541, 537, 538, 549, 539, + 543, 547, 552, 535, 550, 553, 551, 544, 542, 546, + 554, 550, 555, 549, 557, 556, 558, 559, 560, 552, + + 561, 563, 557, 558, 559, 567, 553, 573, 554, 548, + 569, 545, 567, 540, 534, 555, 556, 526, 563, 569, + 512, 511, 509, 561, 505, 500, 498, 560, 573, 576, + 576, 576, 576, 577, 577, 579, 497, 579, 579, 496, + 491, 486, 476, 467, 461, 460, 458, 456, 450, 449, + 448, 447, 444, 443, 442, 441, 440, 437, 433, 432, + 431, 430, 428, 423, 420, 419, 418, 415, 414, 413, + 405, 402, 396, 390, 389, 387, 386, 382, 378, 377, + 376, 375, 374, 373, 372, 369, 361, 350, 349, 347, + 332, 329, 327, 324, 322, 317, 310, 309, 307, 305, + + 302, 299, 294, 287, 281, 278, 277, 276, 265, 264, + 259, 243, 242, 241, 238, 226, 201, 195, 193, 185, + 184, 181, 178, 177, 150, 143, 138, 136, 133, 130, + 126, 122, 106, 90, 59, 39, 37, 8, 7, 3, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575 } ; static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; @@ -845,7 +893,7 @@ goto find_rule; \ #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 1 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" #define INITIAL 0 /*===-- Lexer.l - Scanner for llvm assembly files --------------*- C++ -*--===// // @@ -860,7 +908,7 @@ char *yytext; // //===----------------------------------------------------------------------===*/ #define YY_NEVER_INTERACTIVE 1 -#line 28 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 28 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" #include "ParserInternals.h" #include "llvm/Module.h" #include <list> @@ -887,6 +935,17 @@ void set_scan_string (const char * str) { llvmAsmlval.type.obsolete = true; \ return sym +// Construct a token value for a non-obsolete type +#define RET_TY(CType, sym) \ + llvmAsmlval.TypeVal.type = new PATypeHolder(CType); \ + llvmAsmlval.TypeVal.signedness = isSignless; \ + return sym + +// Construct a token value for an obsolete token +#define RET_TY_OBSOLETE(CType, sign, sym) \ + llvmAsmlval.TypeVal.type = new PATypeHolder(CType); \ + llvmAsmlval.TypeVal.signedness = sign; \ + return sym namespace llvm { @@ -996,7 +1055,7 @@ using namespace llvm; /* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing * it to deal with 64 bit numbers. */ -#line 1000 "Lexer.cpp" +#line 1059 "Lexer.cpp" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -1144,13 +1203,13 @@ YY_MALLOC_DECL YY_DECL { register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; + register char *yy_cp = NULL, *yy_bp = NULL; register int yy_act; -#line 189 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 200 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" -#line 1154 "Lexer.cpp" +#line 1213 "Lexer.cpp" if ( yy_init ) { @@ -1198,14 +1257,14 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 526 ) + if ( yy_current_state >= 576 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *yy_state_ptr++ = yy_current_state; ++yy_cp; } - while ( yy_current_state != 525 ); + while ( yy_current_state != 575 ); yy_find_action: yy_current_state = *--yy_state_ptr; @@ -1243,546 +1302,616 @@ do_action: /* This label is used only to access EOF actions. */ { /* beginning of action switch */ case 1: YY_RULE_SETUP -#line 191 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 202 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { /* Ignore comments for now */ } YY_BREAK case 2: YY_RULE_SETUP -#line 193 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 204 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return BEGINTOK; } YY_BREAK case 3: YY_RULE_SETUP -#line 194 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 205 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return ENDTOK; } YY_BREAK case 4: YY_RULE_SETUP -#line 195 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 206 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return TRUETOK; } YY_BREAK case 5: YY_RULE_SETUP -#line 196 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 207 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return FALSETOK; } YY_BREAK case 6: YY_RULE_SETUP -#line 197 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 208 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return DECLARE; } YY_BREAK case 7: YY_RULE_SETUP -#line 198 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 209 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return GLOBAL; } YY_BREAK case 8: YY_RULE_SETUP -#line 199 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 210 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return CONSTANT; } YY_BREAK case 9: YY_RULE_SETUP -#line 200 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 211 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return INTERNAL; } YY_BREAK case 10: YY_RULE_SETUP -#line 201 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 212 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return LINKONCE; } YY_BREAK case 11: YY_RULE_SETUP -#line 202 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 213 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return WEAK; } YY_BREAK case 12: YY_RULE_SETUP -#line 203 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 214 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return APPENDING; } YY_BREAK case 13: YY_RULE_SETUP -#line 204 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 215 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return DLLIMPORT; } YY_BREAK case 14: YY_RULE_SETUP -#line 205 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 216 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return DLLEXPORT; } YY_BREAK case 15: YY_RULE_SETUP -#line 206 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 217 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return EXTERN_WEAK; } YY_BREAK case 16: YY_RULE_SETUP -#line 207 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 218 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return EXTERNAL; } /* Deprecated, turn into external */ YY_BREAK case 17: YY_RULE_SETUP -#line 208 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 219 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return EXTERNAL; } YY_BREAK case 18: YY_RULE_SETUP -#line 209 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 220 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return IMPLEMENTATION; } YY_BREAK case 19: YY_RULE_SETUP -#line 210 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 221 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return ZEROINITIALIZER; } YY_BREAK case 20: YY_RULE_SETUP -#line 211 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 222 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return DOTDOTDOT; } YY_BREAK case 21: YY_RULE_SETUP -#line 212 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 223 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return UNDEF; } YY_BREAK case 22: YY_RULE_SETUP -#line 213 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 224 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return NULL_TOK; } YY_BREAK case 23: YY_RULE_SETUP -#line 214 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 225 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return TO; } YY_BREAK case 24: YY_RULE_SETUP -#line 215 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 226 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(TermOpVal, Unwind, UNWIND); } YY_BREAK case 25: YY_RULE_SETUP -#line 216 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 227 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return NOT; } /* Deprecated, turned into XOR */ YY_BREAK case 26: YY_RULE_SETUP -#line 217 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 228 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return TAIL; } YY_BREAK case 27: YY_RULE_SETUP -#line 218 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 229 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return TARGET; } YY_BREAK case 28: YY_RULE_SETUP -#line 219 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 230 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return TRIPLE; } YY_BREAK case 29: YY_RULE_SETUP -#line 220 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 231 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return DEPLIBS; } YY_BREAK case 30: YY_RULE_SETUP -#line 221 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 232 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return ENDIAN; } YY_BREAK case 31: YY_RULE_SETUP -#line 222 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 233 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return POINTERSIZE; } YY_BREAK case 32: YY_RULE_SETUP -#line 223 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 234 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return DATALAYOUT; } YY_BREAK case 33: YY_RULE_SETUP -#line 224 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 235 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return LITTLE; } YY_BREAK case 34: YY_RULE_SETUP -#line 225 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 236 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return BIG; } YY_BREAK case 35: YY_RULE_SETUP -#line 226 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 237 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return VOLATILE; } YY_BREAK case 36: YY_RULE_SETUP -#line 227 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 238 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return ALIGN; } YY_BREAK case 37: YY_RULE_SETUP -#line 228 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 239 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return SECTION; } YY_BREAK case 38: YY_RULE_SETUP -#line 229 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 240 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return MODULE; } YY_BREAK case 39: YY_RULE_SETUP -#line 230 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 241 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return ASM_TOK; } YY_BREAK case 40: YY_RULE_SETUP -#line 231 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 242 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return SIDEEFFECT; } YY_BREAK case 41: YY_RULE_SETUP -#line 233 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 244 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return CC_TOK; } YY_BREAK case 42: YY_RULE_SETUP -#line 234 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 245 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return CCC_TOK; } YY_BREAK case 43: YY_RULE_SETUP -#line 235 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 246 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return CSRETCC_TOK; } YY_BREAK case 44: YY_RULE_SETUP -#line 236 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 247 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return FASTCC_TOK; } YY_BREAK case 45: YY_RULE_SETUP -#line 237 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 248 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return COLDCC_TOK; } YY_BREAK case 46: YY_RULE_SETUP -#line 238 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 249 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return X86_STDCALLCC_TOK; } YY_BREAK case 47: YY_RULE_SETUP -#line 239 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 250 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return X86_FASTCALLCC_TOK; } YY_BREAK case 48: YY_RULE_SETUP -#line 241 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } +#line 252 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY(Type::VoidTy, VOID); } YY_BREAK case 49: YY_RULE_SETUP -#line 242 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } +#line 253 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY(Type::BoolTy, BOOL); } YY_BREAK case 50: YY_RULE_SETUP -#line 243 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::SByteTy ; return SBYTE; } +#line 254 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::SByteTy, isSigned, SBYTE); } YY_BREAK case 51: YY_RULE_SETUP -#line 244 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::UByteTy ; return UBYTE; } +#line 255 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::UByteTy, isUnsigned, UBYTE); } YY_BREAK case 52: YY_RULE_SETUP -#line 245 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::ShortTy ; return SHORT; } +#line 256 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::ShortTy, isSigned, SHORT); } YY_BREAK case 53: YY_RULE_SETUP -#line 246 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::UShortTy; return USHORT; } +#line 257 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::UShortTy,isUnsigned, USHORT); } YY_BREAK case 54: YY_RULE_SETUP -#line 247 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::IntTy ; return INT; } +#line 258 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::IntTy, isSigned, INT); } YY_BREAK case 55: YY_RULE_SETUP -#line 248 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::UIntTy ; return UINT; } +#line 259 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::UIntTy, isUnsigned, UINT); } YY_BREAK case 56: YY_RULE_SETUP -#line 249 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::LongTy ; return LONG; } +#line 260 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::LongTy, isSigned, LONG); } YY_BREAK case 57: YY_RULE_SETUP -#line 250 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::ULongTy ; return ULONG; } +#line 261 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY_OBSOLETE(Type::ULongTy, isUnsigned, ULONG); } YY_BREAK case 58: YY_RULE_SETUP -#line 251 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::FloatTy ; return FLOAT; } +#line 262 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY(Type::FloatTy, FLOAT); } YY_BREAK case 59: YY_RULE_SETUP -#line 252 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::DoubleTy; return DOUBLE; } +#line 263 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY(Type::DoubleTy, DOUBLE); } YY_BREAK case 60: YY_RULE_SETUP -#line 253 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::LabelTy ; return LABEL; } +#line 264 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TY(Type::LabelTy, LABEL); } YY_BREAK case 61: YY_RULE_SETUP -#line 254 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 265 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return TYPE; } YY_BREAK case 62: YY_RULE_SETUP -#line 255 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 266 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return OPAQUE; } YY_BREAK case 63: YY_RULE_SETUP -#line 257 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 268 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, Add, ADD); } YY_BREAK case 64: YY_RULE_SETUP -#line 258 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 269 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, Sub, SUB); } YY_BREAK case 65: YY_RULE_SETUP -#line 259 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 270 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, Mul, MUL); } YY_BREAK case 66: YY_RULE_SETUP -#line 260 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 271 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK_OBSOLETE(BinaryOpVal, UDiv, UDIV); } YY_BREAK case 67: YY_RULE_SETUP -#line 261 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 272 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, UDiv, UDIV); } YY_BREAK case 68: YY_RULE_SETUP -#line 262 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 273 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SDiv, SDIV); } YY_BREAK case 69: YY_RULE_SETUP -#line 263 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 274 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, FDiv, FDIV); } YY_BREAK case 70: YY_RULE_SETUP -#line 264 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 275 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK_OBSOLETE(BinaryOpVal, URem, UREM); } YY_BREAK case 71: YY_RULE_SETUP -#line 265 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 276 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, URem, UREM); } YY_BREAK case 72: YY_RULE_SETUP -#line 266 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 277 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SRem, SREM); } YY_BREAK case 73: YY_RULE_SETUP -#line 267 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 278 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, FRem, FREM); } YY_BREAK case 74: YY_RULE_SETUP -#line 268 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 279 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, And, AND); } YY_BREAK case 75: YY_RULE_SETUP -#line 269 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 280 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, Or , OR ); } YY_BREAK case 76: YY_RULE_SETUP -#line 270 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 281 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, Xor, XOR); } YY_BREAK case 77: YY_RULE_SETUP -#line 271 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 282 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SetNE, SETNE); } YY_BREAK case 78: YY_RULE_SETUP -#line 272 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 283 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SetEQ, SETEQ); } YY_BREAK case 79: YY_RULE_SETUP -#line 273 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 284 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SetLT, SETLT); } YY_BREAK case 80: YY_RULE_SETUP -#line 274 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 285 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SetGT, SETGT); } YY_BREAK case 81: YY_RULE_SETUP -#line 275 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 286 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SetLE, SETLE); } YY_BREAK case 82: YY_RULE_SETUP -#line 276 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 287 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(BinaryOpVal, SetGE, SETGE); } YY_BREAK case 83: YY_RULE_SETUP -#line 278 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 289 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(OtherOpVal, PHI, PHI_TOK); } YY_BREAK case 84: YY_RULE_SETUP -#line 279 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 290 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { RET_TOK(OtherOpVal, Call, CALL); } YY_BREAK case 85: YY_RULE_SETUP -#line 280 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Cast, CAST); } +#line 291 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK_OBSOLETE(CastOpVal, Trunc, TRUNC); } YY_BREAK case 86: YY_RULE_SETUP -#line 281 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Select, SELECT); } +#line 292 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, Trunc, TRUNC); } YY_BREAK case 87: YY_RULE_SETUP -#line 282 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Shl, SHL); } +#line 293 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, ZExt, ZEXT); } YY_BREAK case 88: YY_RULE_SETUP -#line 283 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Shr, SHR); } +#line 294 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, SExt, SEXT); } YY_BREAK case 89: YY_RULE_SETUP -#line 284 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ return VANEXT_old; } +#line 295 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, FPTrunc, FPTRUNC); } YY_BREAK case 90: YY_RULE_SETUP -#line 285 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ return VAARG_old; } +#line 296 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, FPExt, FPEXT); } YY_BREAK case 91: YY_RULE_SETUP -#line 286 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, VAArg , VAARG); } +#line 297 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, UIToFP, UITOFP); } YY_BREAK case 92: YY_RULE_SETUP -#line 287 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Ret, RET); } +#line 298 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, SIToFP, SITOFP); } YY_BREAK case 93: YY_RULE_SETUP -#line 288 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Br, BR); } +#line 299 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, FPToUI, FPTOUI); } YY_BREAK case 94: YY_RULE_SETUP -#line 289 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Switch, SWITCH); } +#line 300 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, FPToSI, FPTOSI); } YY_BREAK case 95: YY_RULE_SETUP -#line 290 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Invoke, INVOKE); } +#line 301 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, IntToPtr, INTTOPTR); } YY_BREAK case 96: YY_RULE_SETUP -#line 291 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Unwind, UNWIND); } +#line 302 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, PtrToInt, PTRTOINT); } YY_BREAK case 97: YY_RULE_SETUP -#line 292 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Unreachable, UNREACHABLE); } +#line 303 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(CastOpVal, BitCast, BITCAST); } YY_BREAK case 98: YY_RULE_SETUP -#line 294 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Malloc, MALLOC); } +#line 304 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Select, SELECT); } YY_BREAK case 99: YY_RULE_SETUP -#line 295 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Alloca, ALLOCA); } +#line 305 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Shl, SHL); } YY_BREAK case 100: YY_RULE_SETUP -#line 296 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Free, FREE); } +#line 306 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK_OBSOLETE(OtherOpVal, LShr, LSHR); } YY_BREAK case 101: YY_RULE_SETUP -#line 297 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Load, LOAD); } +#line 307 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, LShr, LSHR); } YY_BREAK case 102: YY_RULE_SETUP -#line 298 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Store, STORE); } +#line 308 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, AShr, ASHR); } YY_BREAK case 103: YY_RULE_SETUP -#line 299 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, GetElementPtr, GETELEMENTPTR); } +#line 309 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ return VANEXT_old; } YY_BREAK case 104: YY_RULE_SETUP -#line 301 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, ExtractElement, EXTRACTELEMENT); } +#line 310 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ return VAARG_old; } YY_BREAK case 105: YY_RULE_SETUP -#line 302 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, InsertElement, INSERTELEMENT); } +#line 311 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, VAArg , VAARG); } YY_BREAK case 106: YY_RULE_SETUP -#line 303 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); } +#line 312 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Ret, RET); } YY_BREAK case 107: YY_RULE_SETUP -#line 306 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 313 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Br, BR); } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 314 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Switch, SWITCH); } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 315 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Invoke, INVOKE); } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 316 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Unwind, UNWIND); } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 317 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Unreachable, UNREACHABLE); } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 319 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Malloc, MALLOC); } + YY_BREAK +case 113: +YY_RULE_SETUP +#line 320 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Alloca, ALLOCA); } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 321 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Free, FREE); } + YY_BREAK +case 115: +YY_RULE_SETUP +#line 322 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Load, LOAD); } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 323 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Store, STORE); } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 324 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, GetElementPtr, GETELEMENTPTR); } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 326 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, ExtractElement, EXTRACTELEMENT); } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 327 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, InsertElement, INSERTELEMENT); } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 328 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); } + YY_BREAK +case 121: +YY_RULE_SETUP +#line 331 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { UnEscapeLexed(yytext+1); llvmAsmlval.StrVal = strdup(yytext+1); // Skip % return VAR_ID; } YY_BREAK -case 108: +case 122: YY_RULE_SETUP -#line 311 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 336 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { yytext[strlen(yytext)-1] = 0; // nuke colon UnEscapeLexed(yytext); @@ -1790,9 +1919,9 @@ YY_RULE_SETUP return LABELSTR; } YY_BREAK -case 109: +case 123: YY_RULE_SETUP -#line 317 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 342 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { yytext[strlen(yytext)-2] = 0; // nuke colon, end quote UnEscapeLexed(yytext+1); @@ -1800,9 +1929,9 @@ YY_RULE_SETUP return LABELSTR; } YY_BREAK -case 110: +case 124: YY_RULE_SETUP -#line 324 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 349 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { // Note that we cannot unescape a string constant here! The // string constant might contain a \00 which would not be // understood by the string stuff. It is valid to make a @@ -1813,14 +1942,14 @@ YY_RULE_SETUP return STRINGCONSTANT; } YY_BREAK -case 111: +case 125: YY_RULE_SETUP -#line 335 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 360 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { llvmAsmlval.UInt64Val = atoull(yytext); return EUINT64VAL; } YY_BREAK -case 112: +case 126: YY_RULE_SETUP -#line 336 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 361 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { uint64_t Val = atoull(yytext+1); // +1: we have bigger negative range @@ -1830,17 +1959,17 @@ YY_RULE_SETUP return ESINT64VAL; } YY_BREAK -case 113: +case 127: YY_RULE_SETUP -#line 344 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 369 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { llvmAsmlval.UInt64Val = HexIntToVal(yytext+3); return yytext[0] == 's' ? ESINT64VAL : EUINT64VAL; } YY_BREAK -case 114: +case 128: YY_RULE_SETUP -#line 349 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 374 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { uint64_t Val = atoull(yytext+1); if ((unsigned)Val != Val) @@ -1849,9 +1978,9 @@ YY_RULE_SETUP return UINTVAL; } YY_BREAK -case 115: +case 129: YY_RULE_SETUP -#line 356 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 381 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { uint64_t Val = atoull(yytext+2); // +1: we have bigger negative range @@ -1861,18 +1990,18 @@ YY_RULE_SETUP return SINTVAL; } YY_BREAK -case 116: +case 130: YY_RULE_SETUP -#line 365 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 390 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { llvmAsmlval.FPVal = atof(yytext); return FPVAL; } YY_BREAK -case 117: +case 131: YY_RULE_SETUP -#line 366 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 391 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { llvmAsmlval.FPVal = HexToFP(yytext); return FPVAL; } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 368 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 393 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { /* Make sure to free the internal buffers for flex when we are * done reading our input! @@ -1881,22 +2010,22 @@ case YY_STATE_EOF(INITIAL): return EOF; } YY_BREAK -case 118: +case 132: YY_RULE_SETUP -#line 376 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 401 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { /* Ignore whitespace */ } YY_BREAK -case 119: +case 133: YY_RULE_SETUP -#line 377 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 402 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" { return yytext[0]; } YY_BREAK -case 120: +case 134: YY_RULE_SETUP -#line 379 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 404 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1900 "Lexer.cpp" +#line 2029 "Lexer.cpp" case YY_END_OF_BUFFER: { @@ -2183,7 +2312,7 @@ static yy_state_type yy_get_previous_state() while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 526 ) + if ( yy_current_state >= 576 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2213,11 +2342,11 @@ yy_state_type yy_current_state; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 526 ) + if ( yy_current_state >= 576 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 525); + yy_is_jam = (yy_current_state == 575); if ( ! yy_is_jam ) *yy_state_ptr++ = yy_current_state; @@ -2272,6 +2401,7 @@ register char *yy_bp; #endif /* ifndef YY_NO_UNPUT */ +#ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput() #else @@ -2345,7 +2475,7 @@ static int input() return c; } - +#endif /* YY_NO_INPUT */ #ifdef YY_USE_PROTOS void yyrestart( FILE *input_file ) @@ -2456,11 +2586,6 @@ YY_BUFFER_STATE b; } -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif #ifdef YY_USE_PROTOS void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) @@ -2778,5 +2903,5 @@ int main() return 0; } #endif -#line 379 "/Users/sabre/cvs/llvm/lib/AsmParser/Lexer.l" +#line 404 "/proj/llvm/llvm-1/lib/AsmParser/Lexer.l" diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 717e583291..b47ae910c7 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -288,7 +288,19 @@ setge { RET_TOK(BinaryOpVal, SetGE, SETGE); } phi { RET_TOK(OtherOpVal, PHI, PHI_TOK); } call { RET_TOK(OtherOpVal, Call, CALL); } -cast { RET_TOK(OtherOpVal, Cast, CAST); } +cast { RET_TOK_OBSOLETE(CastOpVal, Trunc, TRUNC); } +trunc { RET_TOK(CastOpVal, Trunc, TRUNC); } +zext { RET_TOK(CastOpVal, ZExt, ZEXT); } +sext { RET_TOK(CastOpVal, SExt, SEXT); } +fptrunc { RET_TOK(CastOpVal, FPTrunc, FPTRUNC); } +fpext { RET_TOK(CastOpVal, FPExt, FPEXT); } +uitofp { RET_TOK(CastOpVal, UIToFP, UITOFP); } +sitofp { RET_TOK(CastOpVal, SIToFP, SITOFP); } +fptoui { RET_TOK(CastOpVal, FPToUI, FPTOUI); } +fptosi { RET_TOK(CastOpVal, FPToSI, FPTOSI); } +inttoptr { RET_TOK(CastOpVal, IntToPtr, INTTOPTR); } +ptrtoint { RET_TOK(CastOpVal, PtrToInt, PTRTOINT); } +bitcast { RET_TOK(CastOpVal, BitCast, BITCAST); } select { RET_TOK(OtherOpVal, Select, SELECT); } shl { RET_TOK(OtherOpVal, Shl, SHL); } shr { RET_TOK_OBSOLETE(OtherOpVal, LShr, LSHR); } diff --git a/lib/AsmParser/Lexer.l.cvs b/lib/AsmParser/Lexer.l.cvs index 4df84f685e..b47ae910c7 100644 --- a/lib/AsmParser/Lexer.l.cvs +++ b/lib/AsmParser/Lexer.l.cvs @@ -51,6 +51,17 @@ void set_scan_string (const char * str) { llvmAsmlval.type.obsolete = true; \ return sym +// Construct a token value for a non-obsolete type +#define RET_TY(CType, sym) \ + llvmAsmlval.TypeVal.type = new PATypeHolder(CType); \ + llvmAsmlval.TypeVal.signedness = isSignless; \ + return sym + +// Construct a token value for an obsolete token +#define RET_TY_OBSOLETE(CType, sign, sym) \ + llvmAsmlval.TypeVal.type = new PATypeHolder(CType); \ + llvmAsmlval.TypeVal.signedness = sign; \ + return sym namespace llvm { @@ -238,19 +249,19 @@ coldcc { return COLDCC_TOK; } x86_stdcallcc { return X86_STDCALLCC_TOK; } x86_fastcallcc { return X86_FASTCALLCC_TOK; } -void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } -bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } -sbyte { llvmAsmlval.PrimType = Type::SByteTy ; return SBYTE; } -ubyte { llvmAsmlval.PrimType = Type::UByteTy ; return UBYTE; } -short { llvmAsmlval.PrimType = Type::ShortTy ; return SHORT; } -ushort { llvmAsmlval.PrimType = Type::UShortTy; return USHORT; } -int { llvmAsmlval.PrimType = Type::IntTy ; return INT; } -uint { llvmAsmlval.PrimType = Type::UIntTy ; return UINT; } -long { llvmAsmlval.PrimType = Type::LongTy ; return LONG; } -ulong { llvmAsmlval.PrimType = Type::ULongTy ; return ULONG; } -float { llvmAsmlval.PrimType = Type::FloatTy ; return FLOAT; } -double { llvmAsmlval.PrimType = Type::DoubleTy; return DOUBLE; } -label { llvmAsmlval.PrimType = Type::LabelTy ; return LABEL; } +void { RET_TY(Type::VoidTy, VOID); } +bool { RET_TY(Type::BoolTy, BOOL); } +sbyte { RET_TY_OBSOLETE(Type::SByteTy, isSigned, SBYTE); } +ubyte { RET_TY_OBSOLETE(Type::UByteTy, isUnsigned, UBYTE); } +short { RET_TY_OBSOLETE(Type::ShortTy, isSigned, SHORT); } +ushort { RET_TY_OBSOLETE(Type::UShortTy,isUnsigned, USHORT); } +int { RET_TY_OBSOLETE(Type::IntTy, isSigned, INT); } +uint { RET_TY_OBSOLETE(Type::UIntTy, isUnsigned, UINT); } +long { RET_TY_OBSOLETE(Type::LongTy, isSigned, LONG); } +ulong { RET_TY_OBSOLETE(Type::ULongTy, isUnsigned, ULONG); } +float { RET_TY(Type::FloatTy, FLOAT); } +double { RET_TY(Type::DoubleTy, DOUBLE); } +label { RET_TY(Type::LabelTy, LABEL); } type { return TYPE; } opaque { return OPAQUE; } @@ -277,10 +288,24 @@ setge { RET_TOK(BinaryOpVal, SetGE, SETGE); } phi { RET_TOK(OtherOpVal, PHI, PHI_TOK); } call { RET_TOK(OtherOpVal, Call, CALL); } -cast { RET_TOK(OtherOpVal, Cast, CAST); } +cast { RET_TOK_OBSOLETE(CastOpVal, Trunc, TRUNC); } +trunc { RET_TOK(CastOpVal, Trunc, TRUNC); } +zext { RET_TOK(CastOpVal, ZExt, ZEXT); } +sext { RET_TOK(CastOpVal, SExt, SEXT); } +fptrunc { RET_TOK(CastOpVal, FPTrunc, FPTRUNC); } +fpext { RET_TOK(CastOpVal, FPExt, FPEXT); } +uitofp { RET_TOK(CastOpVal, UIToFP, UITOFP); } +sitofp { RET_TOK(CastOpVal, SIToFP, SITOFP); } +fptoui { RET_TOK(CastOpVal, FPToUI, FPTOUI); } +fptosi { RET_TOK(CastOpVal, FPToSI, FPTOSI); } +inttoptr { RET_TOK(CastOpVal, IntToPtr, INTTOPTR); } +ptrtoint { RET_TOK(CastOpVal, PtrToInt, PTRTOINT); } +bitcast { RET_TOK(CastOpVal, BitCast, BITCAST); } select { RET_TOK(OtherOpVal, Select, SELECT); } shl { RET_TOK(OtherOpVal, Shl, SHL); } -shr { RET_TOK(OtherOpVal, Shr, SHR); } +shr { RET_TOK_OBSOLETE(OtherOpVal, LShr, LSHR); } +lshr { RET_TOK(OtherOpVal, LShr, LSHR); } +ashr { RET_TOK(OtherOpVal, AShr, ASHR); } vanext { return VANEXT_old; } vaarg { return VAARG_old; } va_arg { RET_TOK(OtherOpVal, VAArg , VAARG); } diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h index c26c5f4ffb..87c6af7b4a 100644 --- a/lib/AsmParser/ParserInternals.h +++ b/lib/AsmParser/ParserInternals.h @@ -212,10 +212,11 @@ struct OpcodeInfo { Enum opcode; bool obsolete; }; -typedef OpcodeInfo<llvm::Instruction::BinaryOps> BinaryOpInfo; -typedef OpcodeInfo<llvm::Instruction::TermOps> TermOpInfo; -typedef OpcodeInfo<llvm::Instruction::MemoryOps> MemOpInfo; -typedef OpcodeInfo<llvm::Instruction::OtherOps> OtherOpInfo; +typedef OpcodeInfo<llvm::Instruction::BinaryOps> BinaryOpInfo; +typedef OpcodeInfo<llvm::Instruction::TermOps> TermOpInfo; +typedef OpcodeInfo<llvm::Instruction::MemoryOps> MemOpInfo; +typedef OpcodeInfo<llvm::Instruction::CastOps> CastOpInfo; +typedef OpcodeInfo<llvm::Instruction::OtherOps> OtherOpInfo; /// This enumeration is used to indicate if a type is signed, signless or /// unsigned. It is used for backwards compatibility with assembly code that diff --git a/lib/AsmParser/llvmAsmParser.cpp.cvs b/lib/AsmParser/llvmAsmParser.cpp.cvs index c2742e7dbf..c5774e146b 100644 --- a/lib/AsmParser/llvmAsmParser.cpp.cvs +++ b/lib/AsmParser/llvmAsmParser.cpp.cvs @@ -163,18 +163,29 @@ LOAD = 354, STORE = 355, GETELEMENTPTR = 356, - PHI_TOK = 357, - CAST = 358, - SELECT = 359, - SHL = 360, - LSHR = 361, - ASHR = 362, - VAARG = 363, - EXTRACTELEMENT = 364, - INSERTELEMENT = 365, - SHUFFLEVECTOR = 366, - VAARG_old = 367, - VANEXT_old = 368 + TRUNC = 357, + ZEXT = 358, + SEXT = 359, + FPTRUNC = 360, + FPEXT = 361, + BITCAST = 362, + UITOFP = 363, + SITOFP = 364, + FPTOUI = 365, + FPTOSI = 366, + INTTOPTR = 367, + PTRTOINT = 368, + PHI_TOK = 369, + SELECT = 370, + SHL = 371, + LSHR = 372, + ASHR = 373, + VAARG = 374, + EXTRACTELEMENT = 375, + INSERTELEMENT = 376, + SHUFFLEVECTOR = 377, + VAARG_old = 378, + VANEXT_old = 379 }; #endif /* Tokens. */ @@ -277,24 +288,35 @@ #define LOAD 354 #define STORE 355 #define GETELEMENTPTR 356 -#define PHI_TOK 357 -#define CAST 358 -#define SELECT 359 -#define SHL 360 -#define LSHR 361 -#define ASHR 362 -#define VAARG 363 -#define EXTRACTELEMENT 364 -#define INSERTELEMENT 365 -#define SHUFFLEVECTOR 366 -#define VAARG_old 367 -#define VANEXT_old 368 +#define TRUNC 357 +#define ZEXT 358 +#define SEXT 359 +#define FPTRUNC 360 +#define FPEXT 361 +#define BITCAST 362 +#define UITOFP 363 +#define SITOFP 364 +#define FPTOUI 365 +#define FPTOSI 366 +#define INTTOPTR 367 +#define PTRTOINT 368 +#define PHI_TOK 369 +#define SELECT 370 +#define SHL 371 +#define LSHR 372 +#define ASHR 373 +#define VAARG 374 +#define EXTRACTELEMENT 375 +#define INSERTELEMENT 376 +#define SHUFFLEVECTOR 377 +#define VAARG_old 378 +#define VANEXT_old 379 /* Copy the first part of user declarations. */ -#line 14 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" +#line 14 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" #include "ParserInternals.h" #include "llvm/CallingConv.h" @@ -367,8 +389,8 @@ static struct PerModuleInfo { Module *CurrentModule; std::map<const Type *, ValueList> Values; // Module level numbered definitions std::map<const Type *,ValueList> LateResolveValues; - std::vector<PATypeHolder> Types; - std::map<ValID, PATypeHolder> LateResolveTypes; + std::vector<TypeInfo> Types; + std::map<ValID, TypeInfo> LateResolveTypes; /// PlaceHolderInfo - When temporary placeholder objects are created, remember /// how they were referenced and on which line of the input they came from so @@ -501,7 +523,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { case ValID::NumberVal: // Is it a numbered definition? // Module constants occupy the lowest numbered slots... if ((unsigned)D.Num < CurModule.Types.size()) - return CurModule.Types[(unsigned)D.Num]; + return CurModule.Types[(unsigned)D.Num].type->get(); break; case ValID::NameVal: // Is it a named definition? if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) { @@ -531,13 +553,15 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { } } - std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D); + std::map<ValID, TypeInfo>::iterator I =CurModule.LateResolveTypes.find(D); if (I != CurModule.LateResolveTypes.end()) - return I->second; + return I->second.type->get(); - Type *Typ = OpaqueType::get(); - CurModule.LateResolveTypes.insert(std::make_pair(D, Typ)); - return Typ; + TypeInfo TI; + TI.type = new PATypeHolder(OpaqueType::get()); + TI.signedness = isSignless; + CurModule.LateResolveTypes.insert(std::make_pair(D, TI)); + return TI.type->get(); } static Value *lookupInSymbolTable(const Type *Ty, const std::string &Name) { @@ -841,10 +865,10 @@ static void ResolveTypeTo(char *Name, const Type *ToTy) { if (Name) D = ValID::create(Name); else D = ValID::create((int)CurModule.Types.size()); - std::map<ValID, PATypeHolder>::iterator I = + std::map<ValID, TypeInfo>::iterator I = CurModule.LateResolveTypes.find(D); if (I != CurModule.LateResolveTypes.end()) { - ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); + ((DerivedType*)I->second.type->get())->refineAbstractTypeTo(ToTy); CurModule.LateResolveTypes.erase(I); } } @@ -1106,15 +1130,14 @@ static PATypeHolder HandleUpRefs(const Type *ty) { /// instruction. This function handles converting div -> [usf]div appropriately. /// @brief Convert obsolete BinaryOps opcodes to new values static void -sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy) +sanitizeOpcode(OpcodeInfo<Instruction::BinaryOps> &OI, const Type *Ty) { // If its not obsolete, don't do anything if (!OI.obsolete) return; // If its a packed type we want to use the element type - const Type* Ty = PATy; - if (const PackedType* PTy = dyn_cast<PackedType>(Ty)) + if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) Ty = PTy->getElementType(); // Depending on the opcode .. @@ -1140,17 +1163,16 @@ sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy) OI.obsolete = false; } -/// This function is similar to the previous overload of sanitizeOpCode but +/// This function is similar to the previous overload of sanitizeOpcode but /// operates on Instruction::OtherOps instead of Instruction::BinaryOps. /// @brief Convert obsolete OtherOps opcodes to new values static void -sanitizeOpCode(OpcodeInfo<Instruction::OtherOps> &OI, const PATypeHolder& PATy) +sanitizeOpcode(OpcodeInfo<Instruction::OtherOps> &OI, const Type *Ty) { // If its not obsolete, don't do anything if (!OI.obsolete) return; - const Type* Ty = PATy; // type conversion switch (OI.opcode) { default: GenerateError("Invalid obsolete opcode (check Lexer.l)"); @@ -1340,23 +1362,22 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { #endif #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 1040 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" +#line 1040 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" typedef union YYSTYPE { llvm::Module *ModuleVal; llvm::Function *FunctionVal; - std::pair<llvm::PATypeHolder*, char*> *ArgVal; + std::pair<TypeInfo, char*> *ArgVal; llvm::BasicBlock *BasicBlockVal; llvm::TerminatorInst *TermInstVal; llvm::Instruction *InstVal; llvm::Constant *ConstVal; - const llvm::Type *PrimType; - llvm::PATypeHolder *TypeVal; + TypeInfo TypeVal; llvm::Value *ValueVal; - std::vector<std::pair<llvm::PATypeHolder*,char*> > *ArgList; + std::vector<std::pair<TypeInfo,char*> >*ArgList; std::vector<llvm::Value*> *ValueList; - std::list<llvm::PATypeHolder> *TypeList; + std::list<TypeInfo> *TypeList; // Represent the RHS of PHI node std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *PHIList; @@ -1377,11 +1398,12 @@ typedef union YYSTYPE { BinaryOpInfo BinaryOpVal; TermOpInfo TermOpVal; MemOpInfo MemOpVal; + CastOpInfo CastOpVal; OtherOpInfo OtherOpVal; llvm::Module::Endianness Endianness; } YYSTYPE; /* Line 196 of yacc.c. */ -#line 1385 "llvmAsmParser.tab.c" +#line 1407 "llvmAsmParser.tab.c" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 @@ -1393,7 +1415,7 @@ typedef union YYSTYPE { /* Line 219 of yacc.c. */ -#line 1397 "llvmAsmParser.tab.c" +#line 1419 "llvmAsmParser.tab.c" #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ @@ -1544,20 +1566,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 4 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1310 +#define YYLAST 1410 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 128 +#define YYNTOKENS 139 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 75 +#define YYNNTS 76 /* YYNRULES -- Number of rules. */ -#define YYNRULES 257 +#define YYNRULES 269 /* YYNRULES -- Number of states. */ -#define YYNSTATES 522 +#define YYNSTATES 534 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 368 +#define YYMAXUTOK 379 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -1569,15 +1591,15 @@ static const unsigned char yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 117, 118, 126, 2, 115, 2, 2, 2, 2, 2, + 128, 129, 137, 2, 126, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 122, 114, 123, 2, 2, 2, 2, 2, 2, 2, + 133, 125, 134, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 119, 116, 121, 2, 2, 2, 2, 2, 127, + 2, 130, 127, 132, 2, 2, 2, 2, 2, 138, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 120, 2, 2, 124, 2, 125, 2, 2, 2, 2, + 131, 2, 2, 135, 2, 136, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1601,7 +1623,8 @@ static const unsigned char yytranslate[] = 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113 + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124 }; #if YYDEBUG @@ -1613,147 +1636,152 @@ static const unsigned short int yyprhs[] = 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, - 80, 81, 83, 85, 87, 89, 91, 93, 95, 96, - 97, 99, 101, 103, 105, 107, 109, 112, 113, 116, - 117, 121, 124, 125, 127, 128, 132, 134, 137, 139, - 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, + 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, + 99, 101, 104, 105, 107, 109, 111, 113, 115, 117, + 119, 120, 121, 123, 125, 127, 129, 131, 133, 136, + 137, 140, 141, 145, 148, 149, 151, 152, 156, 158, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, - 182, 187, 193, 199, 203, 206, 209, 211, 215, 217, - 221, 223, 224, 229, 233, 237, 242, 247, 251, 254, - 257, 260, 263, 266, 269, 272, 275, 278, 281, 288, - 294, 303, 310, 317, 324, 331, 338, 347, 356, 360, - 362, 364, 366, 368, 371, 374, 379, 382, 384, 389, - 392, 397, 398, 406, 407, 415, 416, 424, 425, 433, - 437, 442, 443, 445, 447, 449, 453, 457, 461, 465, - 469, 473, 475, 476, 478, 480, 482, 483, 486, 490, - 492, 494, 498, 500, 501, 510, 512, 514, 518, 520, - 522, 525, 526, 528, 530, 531, 536, 537, 539, 541, - 543, 545, 547, 549, 551, 553, 555, 559, 561, 567, - 569, 571, 573, 575, 578, 581, 584, 588, 591, 592, - 594, 597, 600, 604, 614, 624, 633, 647, 649, 651, - 658, 664, 667, 674, 682, 684, 688, 690, 691, 694, - 696, 702, 708, 714, 717, 722, 727, 734, 739, 744, - 749, 754, 761, 768, 771, 779, 781, 784, 785, 787, - 788, 792, 799, 803, 810, 813, 818, 825 + 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, + 201, 203, 206, 211, 217, 223, 227, 230, 233, 235, + 239, 241, 245, 247, 248, 253, 257, 261, 266, 271, + 275, 278, 281, 284, 287, 290, 293, 296, 299, 302, + 305, 312, 318, 327, 334, 341, 348, 355, 362, 371, + 380, 384, 386, 388, 390, 392, 395, 398, 403, 406, + 408, 413, 416, 421, 422, 430, 431, 439, 440, 448, + 449, 457, 461, 466, 467, 469, 471, 473, 477, 481, + 485, 489, 493, 497, 499, 500, 502, 504, 506, 507, + 510, 514, 516, 518, 522, 524, 525, 534, 536, 538, + 542, 544, 546, 549, 550, 552, 554, 555, 560, 561, + 563, 565, 567, 569, 571, 573, 575, 577, 579, 583, + 585, 591, 593, 595, 597, 599, 602, 605, 608, 612, + 615, 616, 618, 621, 624, 628, 638, 648, 657, 671, + 673, 675, 682, 688, 691, 698, 706, 708, 712, 714, + 715, 718, 720, 726, 732, 738, 741, 746, 751, 758, + 763, 768, 773, 778, 785, 792, 795, 803, 805, 808, + 809, 811, 812, 816, 823, 827, 834, 837, 842, 849 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const short int yyrhs[] = { - 159, 0, -1, 5, -1, 6, -1, 3, -1, 4, + 171, 0, -1, 5, -1, 6, -1, 3, -1, 4, -1, 78, -1, 79, -1, 80, -1, 81, -1, 82, -1, 83, -1, 84, -1, 85, -1, 86, -1, 87, -1, 88, -1, 89, -1, 90, -1, 91, -1, 92, - -1, 93, -1, 94, -1, 95, -1, 105, -1, 106, - -1, 107, -1, 16, -1, 14, -1, 12, -1, 10, - -1, 17, -1, 15, -1, 13, -1, 11, -1, 135, - -1, 136, -1, 18, -1, 19, -1, 171, 114, -1, - -1, 41, -1, 42, -1, 43, -1, 44, -1, 45, - -1, 46, -1, 47, -1, -1, -1, 65, -1, 66, - -1, 67, -1, 68, -1, 69, -1, 70, -1, 64, - 4, -1, -1, 57, 4, -1, -1, 115, 57, 4, - -1, 34, 24, -1, -1, 144, -1, -1, 115, 147, - 146, -1, 144, -1, 57, 4, -1, 150, -1, 8, - -1, 152, -1, 8, -1, 152, -1, 9, -1, 10, - -1, 11, -1, 12, -1, 13, -1, 14, -1, 15, - -1, 16, -1, 17, -1, 18, -1, 19, -1, 20, - -1, 21, -1, 48, -1, 151, -1, 186, -1, 116, - 4, -1, 149, 117, 154, 118, -1, 119, 4, 120, - 152, 121, -1, 122, 4, 120, 152, 123, -1, 124, - 153, 125, -1, 124, 125, -1, 152, 126, -1, 152, - -1, 153, 115, 152, -1, 153, -1, 153, 115, 37, - -1, 37, -1, -1, 150, 119, 157, 121, -1, 150, - 119, 121, -1, 150, 127, 24, -1, 150, 122, 157, - 123, -1, 150, 124, 157, 125, -1, 150, 124, 125, - -1, 150, 38, -1, 150, 39, -1, 150, 186, -1, - 150, 156, -1, 150, 26, -1, 135, 130, -1, 136, - 4, -1, 9, 27, -1, 9, 28, -1, 138, 7, - -1, 103, 117, 155, 36, 150, 118, -1, 101, 117, - 155, 200, 118, -1, 104, 117, 155, 115, 155, 115, - 155, 118, -1, 131, 117, 155, 115, 155, 118, -1, - 132, 117, 155, 115, 155, 118, -1, 133, 117, 155, - 115, 155, 118, -1, 134, 117, 155, 115, 155, 118, - -1, 109, 117, 155, 115, 155, 118, -1, 110, 117, - 155, 115, 155, 115, 155, 118, -1, 111, 117, 155, - 115, 155, 115, 155, 118, -1, 157, 115, 155, -1, - 155, -1, 32, -1, 33, -1, 160, -1, 160, 180, - -1, 160, 182, -1, 160, 62, 61, 166, -1, 160, - 25, -1, 161, -1, 161, 139, 20, 148, -1, 161, - 182, -1, 161, 62, 61, 166, -1, -1, 161, 139, - 140, 158, 155, 162, 146, -1, -1, 161, 139, 50, - 158, 150, 163, 146, -1, -1, 161, 139, 45, 158, - 150, 164, 146, -1, -1, 161, 139, 47, 158, 150, - 165, 146, -1, 161, 51, 168, -1, 161, 58, 114, - 169, -1, -1, 24, -1, 56, -1, 55, -1, 53, - 114, 167, -1, 54, 114, 4, -1, 52, 114, 24, - -1, 71, 114, 24, -1, 119, 170, 121, -1, 170, - 115, 24, -1, 24, -1, -1, 22, -1, 24, -1, - 171, -1, -1, 150, 172, -1, 174, 115, 173, -1, - 173, -1, 174, -1, 174, 115, 37, -1, 37, -1, - -1, 141, 148, 171, 117, 175, 118, 145, 142, -1, - 29, -1, 124, -1, 140, 176, 177, -1, 30, -1, - 125, -1, 189, 179, -1, -1, 45, -1, 47, -1, - -1, 31, 183, 181, 176, -1, -1, 63, -1, 3, - -1, 4, -1, 7, -1, 27, -1, 28, -1, 38, - -1, 39, -1, 26, -1, 122, 157, 123, -1, 156, - -1, 61, 184, 24, 115, 24, -1, 129, -1, 171, - -1, 186, -1, 185, -1, 150, 187, -1, 189, 190, - -1, 178, 190, -1, 191, 139, 192, -1, 191, 194, - -1, -1, 23, -1, 72, 188, -1, 72, 8, -1, - 73, 21, 187, -1, 73, 9, 187, 115, 21, 187, - 115, 21, 187, -1, 74, 137, 187, 115, 21, 187, - 119, 193, 121, -1, 74, 137, 187, 115, 21, 187, - 119, 121, -1, 75, 141, 148, 187, 117, 197, 118, - 36, 21, 187, 76, 21, 187, -1, 76, -1, 77, - -1, 193, 137, 185, 115, 21, 187, -1, 137, 185, - 115, 21, 187, -1, 139, 199, -1, 150, 119, 187, - 115, 187, 121, -1, 195, 115, 119, 187, 115, 187, - 121, -1, 188, -1, 196, 115, 188, -1, 196, -1, - -1, 60, 59, -1, 59, -1, 131, 150, 187, 115, - 187, -1, 132, 150, 187, 115, 187, -1, 133, 150, - 187, 115, 187, -1, 49, 188, -1, 134, 188, 115, - 188, -1, 103, 188, 36, 150, -1, 104, 188, 115, - 188, 115, 188, -1, 108, 188, 115, 150, -1, 112, - 188, 115, 150, -1, 113, 188, 115, 150, -1, 109, - 188, 115, 188, -1, 110, 188, 115, 188, 115, 188, - -1, 111, 188, 115, 188, 115, 188, -1, 102, 195, - -1, 198, 141, 148, 187, 117, 197, 118, -1, 202, - -1, 115, 196, -1, -1, 35, -1, -1, 96, 150, - 143, -1, 96, 150, 115, 15, 187, 143, -1, 97, - 150, 143, -1, 97, 150, 115, 15, 187, 143, -1, - 98, 188, -1, 201, 99, 150, 187, -1, 201, 100, - 188, 115, 150, 187, -1, 101, 150, 187, 200, -1 + -1, 93, -1, 94, -1, 95, -1, 102, -1, 103, + -1, 104, -1, 105, -1, 106, -1, 107, -1, 108, + -1, 109, -1, 110, -1, 111, -1, 112, -1, 113, + -1, 116, -1, 117, -1, 118, -1, 16, -1, 14, + -1, 12, -1, 10, -1, 17, -1, 15, -1, 13, + -1, 11, -1, 147, -1, 148, -1, 18, -1, 19, + -1, 183, 125, -1, -1, 41, -1, 42, -1, 43, + -1, 44, -1, 45, -1, 46, -1, 47, -1, -1, + -1, 65, -1, 66, -1, 67, -1, 68, -1, 69, + -1, 70, -1, 64, 4, -1, -1, 57, 4, -1, + -1, 126, 57, 4, -1, 34, 24, -1, -1, 156, + -1, -1, 126, 159, 158, -1, 156, -1, 57, 4, + -1, 162, -1, 8, -1, 164, -1, 8, -1, 164, + -1, 9, -1, 10, -1, 11, -1, 12, -1, 13, + -1, 14, -1, 15, -1, 16, -1, 17, -1, 18, + -1, 19, -1, 20, -1, 21, -1, 48, -1, 163, + -1, 198, -1, 127, 4, -1, 161, 128, 166, 129, + -1, 130, 4, 131, 164, 132, -1, 133, 4, 131, + 164, 134, -1, 135, 165, 136, -1, 135, 136, -1, + 164, 137, -1, 164, -1, 165, 126, 164, -1, 165, + -1, 165, 126, 37, -1, 37, -1, -1, 162, 130, + 169, 132, -1, 162, 130, 132, -1, 162, 138, 24, + -1, 162, 133, 169, 134, -1, 162, 135, 169, 136, + -1, 162, 135, 136, -1, 162, 38, -1, 162, 39, + -1, 162, 198, -1, 162, 168, -1, 162, 26, -1, + 147, 141, -1, 148, 4, -1, 9, 27, -1, 9, + 28, -1, 150, 7, -1, 145, 128, 167, 36, 162, + 129, -1, 101, 128, 167, 212, 129, -1, 115, 128, + 167, 126, 167, 126, 167, 129, -1, 142, 128, 167, + 126, 167, 129, -1, 143, 128, 167, 126, 167, 129, + -1, 144, 128, 167, 126, 167, 129, -1, 146, 128, + 167, 126, 167, 129, -1, 120, 128, 167, 126, 167, + 129, -1, 121, 128, 167, 126, 167, 126, 167, 129, + -1, 122, 128, 167, 126, 167, 126, 167, 129, -1, + 169, 126, 167, -1, 167, -1, 32, -1, 33, -1, + 172, -1, 172, 192, -1, 172, 194, -1, 172, 62, + 61, 178, -1, 172, 25, -1, 173, -1, 173, 151, + 20, 160, -1, 173, 194, -1, 173, 62, 61, 178, + -1, -1, 173, 151, 152, 170, 167, 174, 158, -1, + -1, 173, 151, 50, 170, 162, 175, 158, -1, -1, + 173, 151, 45, 170, 162, 176, 158, -1, -1, 173, + 151, 47, 170, 162, 177, 158, -1, 173, 51, 180, + -1, 173, 58, 125, 181, -1, -1, 24, -1, 56, + -1, 55, -1, 53, 125, 179, -1, 54, 125, 4, + -1, 52, 125, 24, -1, 71, 125, 24, -1, 130, + 182, 132, -1, 182, 126, 24, -1, 24, -1, -1, + 22, -1, 24, -1, 183, -1, -1, 162, 184, -1, + 186, 126, 185, -1, 185, -1, 186, -1, 186, 126, + 37, -1, 37, -1, -1, 153, 160, 183, 128, 187, + 129, 157, 154, -1, 29, -1, 135, -1, 152, 188, + 189, -1, 30, -1, 136, -1, 201, 191, -1, -1, + 45, -1, 47, -1, -1, 31, 195, 193, 188, -1, + -1, 63, -1, 3, -1, 4, -1, 7, -1, 27, + -1, 28, -1, 38, -1, 39, -1, 26, -1, 133, + 169, 134, -1, 168, -1, 61, 196, 24, 126, 24, + -1, 140, -1, 183, -1, 198, -1, 197, -1, 162, + 199, -1, 201, 202, -1, 190, 202, -1, 203, 151, + 204, -1, 203, 206, -1, -1, 23, -1, 72, 200, + -1, 72, 8, -1, 73, 21, 199, -1, 73, 9, + 199, 126, 21, 199, 126, 21, 199, -1, 74, 149, + 199, 126, 21, 199, 130, 205, 132, -1, 74, 149, + 199, 126, 21, 199, 130, 132, -1, 75, 153, 160, + 199, 128, 209, 129, 36, 21, 199, 76, 21, 199, + -1, 76, -1, 77, -1, 205, 149, 197, 126, 21, + 199, -1, 149, 197, 126, 21, 199, -1, 151, 211, + -1, 162, 130, 199, 126, 199, 132, -1, 207, 126, + 130, 199, 126, 199, 132, -1, 200, -1, 208, 126, + 200, -1, 208, -1, -1, 60, 59, -1, 59, -1, + 142, 162, 199, 126, 199, -1, 143, 162, 199, 126, + 199, -1, 144, 162, 199, 126, 199, -1, 49, 200, + -1, 146, 200, 126, 200, -1, 145, 200, 36, 162, + -1, 115, 200, 126, 200, 126, 200, -1, 119, 200, + 126, 162, -1, 123, 200, 126, 162, -1, 124, 200, + 126, 162, -1, 120, 200, 126, 200, -1, 121, 200, + 126, 200, 126, 200, -1, 122, 200, 126, 200, 126, + 200, -1, 114, 207, -1, 210, 153, 160, 199, 128, + 209, 129, -1, 214, -1, 126, 208, -1, -1, 35, + -1, -1, 96, 162, 155, -1, 96, 162, 126, 15, + 199, 155, -1, 97, 162, 155, -1, 97, 162, 126, + 15, 199, 155, -1, 98, 200, -1, 213, 99, 162, + 199, -1, 213, 100, 200, 126, 162, 199, -1, 101, + 162, 199, 212, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const unsigned short int yyrline[] = { - 0, 1163, 1163, 1164, 1172, 1173, 1183, 1183, 1183, 1183, - 1183, 1183, 1183, 1183, 1183, 1184, 1184, 1184, 1185, 1185, - 1185, 1185, 1185, 1185, 1187, 1187, 1187, 1191, 1191, 1191, - 1191, 1192, 1192, 1192, 1192, 1193, 1193, 1194, 1194, 1197, - 1201, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1215, - 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1231, 1232, 1238, - 1239, 1247, 1255, 1256, 1261, 1262, 1263, 1268, 1282, 1282, - 1283, 1283, 1285, 1295, 1295, 1295, 1295, 1295, 1295, 1295, - 1296, 1296, 1296, 1296, 1296, 1296, 1297, 1301, 1305, 1313, - 1321, 1334, 1339, 1351, 1361, 1365, 1376, 1381, 1387, 1388, - 1392, 1396, 1407, 1433, 1447, 1477, 1503, 1524, 1537, 1547, - 1552, 1613, 1620, 1629, 1635, 1641, 1645, 1649, 1657, 1668, - 1700, 1708, 1735, 1746, 1752, 1763, 1769, 1775, 1784, 1788, - 1796, 1796, 1806, 1814, 1819, 1823, 1827, 1831, 1846, 1868, - 1871, 1874, 1874, 1882, 1882, 1890, 1890, 1898, 1898, 1907, - 1910, 1913, 1917, 1930, 1931, 1933, 1937, 1946, 1950, 1955, - 1957, 1962, 1967, 1976, 1976, 1977, 1977, 1979, 1986, 1992, - 1999, 2003, 2009, 2014, 2019, 2114, 2114, 2116, 2124, 2124, - 2126, 2131, 2132, 2133, 2135, 2135, 2145, 2149, 2154, 2158, - 2162, 2166, 2170, 2174, 2178, 2182, 2186, 2211, 2215, 2229, - 2233, 2239, 2239, 2245, 2250, 2254, 2263, 2274, 2279, 2291, - 2304, 2308, 2312, 2317, 2326, 2345, 2354, 2410, 2414, 2421, - 2432, 2445, 2454, 2463, 2473, 2477, 2484, 2484, 2486, 2490, - 2495, 2517, 2532, 2546, 2559, 2570, 2578, 2586, 2592, 2612, - 2635, 2641, 2647, 2653, 2668, 2727, 2734, 2737, 2742, 2746, - 2753, 2758, 2764, 2769, 2775, 2783, 2795, 2810 + 0, 1168, 1168, 1169, 1177, 1178, 1188, 1188, 1188, 1188, + 1188, 1188, 1188, 1188, 1188, 1189, 1189, 1189, 1190, 1190, + 1190, 1190, 1190, 1190, 1191, 1191, 1191, 1191, 1191, 1191, + 1192, 1192, 1192, 1192, 1192, 1192, 1193, 1193, 1193, 1197, + 1197, 1197, 1197, 1198, 1198, 1198, 1198, 1199, 1199, 1200, + 1200, 1203, 1207, 1212, 1213, 1214, 1215, 1216, 1217, 1218, + 1219, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1237, + 1238, 1244, 1245, 1253, 1261, 1262, 1267, 1268, 1269, 1274, + 1288, 1288, 1292, 1292, 1297, 1308, 1308, 1308, 1308, 1308, + 1308, 1308, 1309, 1309, 1309, 1309, 1309, 1309, 1310, 1315, + 1319, 1328, 1337, 1352, 1359, 1373, 1384, 1389, 1401, 1406, + 1412, 1413, 1419, 1425, 1436, 1462, 1476, 1506, 1532, 1553, + 1566, 1576, 1581, 1642, 1649, 1658, 1664, 1670, 1674, 1678, + 1686, 1712, 1744, 1752, 1779, 1790, 1796, 1807, 1813, 1819, + 1828, 1832, 1840, 1840, 1850, 1858, 1863, 1867, 1871, 1875, + 1890, 1912, 1915, 1918, 1918, 1926, 1926, 1935, 1935, 1944, + 1944, 1954, 1957, 1960, 1964, 1977, 1978, 1980, 1984, 1993, + 1997, 2002, 2004, 2009, 2014, 2023, 2023, 2024, 2024, 2026, + 2033, 2039, 2046, 2050, 2058, 2066, 2071, 2165, 2165, 2167, + 2175, 2175, 2177, 2182, 2183, 2184, 2186, 2186, 2196, 2200, + 2205, 2209, 2213, 2217, 2221, 2225, 2229, 2233, 2237, 2257, + 2261, 2275, 2279, 2285, 2285, 2291, 2296, 2300, 2309, 2320, + 2329, 2341, 2354, 2358, 2362, 2367, 2376, 2395, 2404, 2460, + 2464, 2471, 2482, 2495, 2504, 2513, 2523, 2527, 2534, 2534, + 2536, 2540, 2545, 2567, 2582, 2596, 2609, 2620, 2646, 2654, + 2660, 2680, 2703, 2709, 2715, 2721, 2736, 2796, 2803, 2806, + 2811, 2815, 2822, 2827, 2833, 2838, 2844, 2852, 2864, 2879 }; #endif @@ -1777,22 +1805,24 @@ static const char *const yytname[] = "RET", "BR", "SWITCH", "INVOKE", "UNWIND", "UNREACHABLE", "ADD", "SUB", "MUL", "UDIV", "SDIV", "FDIV", "UREM", "SREM", "FREM", "AND", "OR", "XOR", "SETLE", "SETGE", "SETLT", "SETGT", "SETEQ", "SETNE", "MALLOC", - "ALLOCA", "FREE", "LOAD", "STORE", "GETELEMENTPTR", "PHI_TOK", "CAST", - "SELECT", "SHL", "LSHR", "ASHR", "VAARG", "EXTRACTELEMENT", - "INSERTELEMENT", "SHUFFLEVECTOR", "VAARG_old", "VANEXT_old", "'='", - "','", "'\\\\'", "'('", "')'", "'['", "'x'", "']'", "'<'", "'>'", "'{'", - "'}'", "'*'", "'c'", "$accept", "INTVAL", "EINT64VAL", "ArithmeticOps", - "LogicalOps", "SetCondOps", "ShiftOps", "SIntType", "UIntType", - "IntType", "FPType", "OptAssign", "OptLinkage", "OptCallingConv", - "OptAlign", "OptCAlign", "SectionString", "OptSection", - "GlobalVarAttributes", "GlobalVarAttribute", "TypesV", "UpRTypesV", - "Types", "PrimType", "UpRTypes", "TypeListI", "ArgTypeListI", "ConstVal", - "ConstExpr", "ConstVector", "GlobalType", "Module", "FunctionList", - "ConstPool", "@1", "@2", "@3", "@4", "AsmBlock", "BigOrLittle", - "TargetDefinition", "LibrariesDefinition", "LibList", "Name", "OptName", - "ArgVal", "ArgListH", "ArgList", "FunctionHeaderH", "BEGIN", - "FunctionHeader", "END", "Function", "FnDeclareLinkage", "FunctionProto", - "@5", "OptSideEffect", "ConstValueRef", "SymbolicValueRef", "ValueRef", + "ALLOCA", "FREE", "LOAD", "STORE", "GETELEMENTPTR", "TRUNC", "ZEXT", + "SEXT", "FPTRUNC", "FPEXT", "BITCAST", "UITOFP", "SITOFP", "FPTOUI", + "FPTOSI", "INTTOPTR", "PTRTOINT", "PHI_TOK", "SELECT", "SHL", "LSHR", + "ASHR", "VAARG", "EXTRACTELEMENT", "INSERTELEMENT", "SHUFFLEVECTOR", + "VAARG_old", "VANEXT_old", "'='", "','", "'\\\\'", "'('", "')'", "'['", + "'x'", "']'", "'<'", "'>'", "'{'", "'}'", "'*'", "'c'", "$accept", + "INTVAL", "EINT64VAL", "ArithmeticOps", "LogicalOps", "SetCondOps", + "CastOps", "ShiftOps", "SIntType", "UIntType", "IntType", "FPType", + "OptAssign", "OptLinkage", "OptCallingConv", "OptAlign", "OptCAlign", + "SectionString", "OptSection", "GlobalVarAttributes", + "GlobalVarAttribute", "TypesV", "UpRTypesV", "Types", "PrimType", + "UpRTypes", "TypeListI", "ArgTypeListI", "ConstVal", "ConstExpr", + "ConstVector", "GlobalType", "Module", "FunctionList", "ConstPool", "@1", + "@2", "@3", "@4", "AsmBlock", "BigOrLittle", "TargetDefinition", + "LibrariesDefinition", "LibList", "Name", "OptName", "ArgVal", + "ArgListH", "ArgList", "FunctionHeaderH", "BEGIN", "FunctionHeader", + "END", "Function", "FnDeclareLinkage", "FunctionProto", "@5", + "OptSideEffect", "ConstValueRef", "SymbolicValueRef", "ValueRef", "ResolvedVal", "BasicBlockList", "BasicBlock", "InstructionList", "BBTerminatorInst", "JumpTable", "Inst", "PHIList", "ValueRefList", "ValueRefListE", "OptTailCall", "InstVal", "IndexList", "OptVolatile", @@ -1816,40 +1846,42 @@ static const unsigned short int yytoknum[] = 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 61, 44, 92, 40, 41, 91, - 120, 93, 60, 62, 123, 125, 42, 99 + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 61, 44, 92, 40, 41, + 91, 120, 93, 60, 62, 123, 125, 42, 99 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const unsigned char yyr1[] = { - 0, 128, 129, 129, 130, 130, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 132, 132, 132, 133, 133, - 133, 133, 133, 133, 134, 134, 134, 135, 135, 135, - 135, 136, 136, 136, 136, 137, 137, 138, 138, 139, - 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, - 141, 141, 141, 141, 141, 141, 141, 142, 142, 143, - 143, 144, 145, 145, 146, 146, 147, 147, 148, 148, - 149, 149, 150, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 153, 153, 154, 154, - 154, 154, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 156, 156, - 156, 156, 156, 156, 156, 156, 156, 156, 157, 157, - 158, 158, 159, 160, 160, 160, 160, 160, 161, 161, - 161, 162, 161, 163, 161, 164, 161, 165, 161, 161, - 161, 161, 166, 167, 167, 168, 168, 168, 168, 169, - 170, 170, 170, 171, 171, 172, 172, 173, 174, 174, - 175, 175, 175, 175, 176, 177, 177, 178, 179, 179, - 180, 181, 181, 181, 183, 182, 184, 184, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 186, - 186, 187, 187, 188, 189, 189, 190, 191, 191, 191, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 193, - 193, 194, 195, 195, 196, 196, 197, 197, 198, 198, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 200, 200, 201, 201, - 202, 202, 202, 202, 202, 202, 202, 202 + 0, 139, 140, 140, 141, 141, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 143, 143, 143, 144, 144, + 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 146, 146, 146, 147, + 147, 147, 147, 148, 148, 148, 148, 149, 149, 150, + 150, 151, 151, 152, 152, 152, 152, 152, 152, 152, + 152, 153, 153, 153, 153, 153, 153, 153, 153, 154, + 154, 155, 155, 156, 157, 157, 158, 158, 159, 159, + 160, 160, 161, 161, 162, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, + 166, 166, 166, 166, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 169, 169, 170, 170, 171, 172, 172, 172, 172, 172, + 173, 173, 173, 174, 173, 175, 173, 176, 173, 177, + 173, 173, 173, 173, 178, 179, 179, 180, 180, 180, + 180, 181, 182, 182, 182, 183, 183, 184, 184, 185, + 186, 186, 187, 187, 187, 187, 188, 189, 189, 190, + 191, 191, 192, 193, 193, 193, 195, 194, 196, 196, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, + 197, 198, 198, 199, 199, 200, 201, 201, 202, 203, + 203, 203, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 205, 205, 206, 207, 207, 208, 208, 209, 209, + 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 212, 212, + 213, 213, 214, 214, 214, 214, 214, 214, 214, 214 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1858,29 +1890,30 @@ static const unsigned char yyr2[] = 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 2, 0, 2, 0, - 3, 2, 0, 1, 0, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 4, 5, 5, 3, 2, 2, 1, 3, 1, 3, - 1, 0, 4, 3, 3, 4, 4, 3, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 6, 5, - 8, 6, 6, 6, 6, 6, 8, 8, 3, 1, - 1, 1, 1, 2, 2, 4, 2, 1, 4, 2, - 4, 0, 7, 0, 7, 0, 7, 0, 7, 3, - 4, 0, 1, 1, 1, 3, 3, 3, 3, 3, - 3, 1, 0, 1, 1, 1, 0, 2, 3, 1, - 1, 3, 1, 0, 8, 1, 1, 3, 1, 1, - 2, 0, 1, 1, 0, 4, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, 5, 1, - 1, 1, 1, 2, 2, 2, 3, 2, 0, 1, - 2, 2, 3, 9, 9, 8, 13, 1, 1, 6, - 5, 2, 6, 7, 1, 3, 1, 0, 2, 1, - 5, 5, 5, 2, 4, 4, 6, 4, 4, 4, - 4, 6, 6, 2, 7, 1, 2, 0, 1, 0, - 3, 6, 3, 6, 2, 4, 6, 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 2, 0, + 2, 0, 3, 2, 0, 1, 0, 3, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 5, 3, 2, 2, 1, 3, + 1, 3, 1, 0, 4, 3, 3, 4, 4, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 6, 5, 8, 6, 6, 6, 6, 6, 8, 8, + 3, 1, 1, 1, 1, 2, 2, 4, 2, 1, + 4, 2, 4, 0, 7, 0, 7, 0, 7, 0, + 7, 3, 4, 0, 1, 1, 1, 3, 3, 3, + 3, 3, 3, 1, 0, 1, 1, 1, 0, 2, + 3, 1, 1, 3, 1, 0, 8, 1, 1, 3, + 1, 1, 2, 0, 1, 1, 0, 4, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, + 5, 1, 1, 1, 1, 2, 2, 2, 3, 2, + 0, 1, 2, 2, 3, 9, 9, 8, 13, 1, + 1, 6, 5, 2, 6, 7, 1, 3, 1, 0, + 2, 1, 5, 5, 5, 2, 4, 4, 6, 4, + 4, 4, 4, 6, 6, 2, 7, 1, 2, 0, + 1, 0, 3, 6, 3, 6, 2, 4, 6, 4 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1888,481 +1921,504 @@ static const unsigned char yyr2[] = means the default is an error. */ static const unsigned short int yydefact[] = { - 151, 0, 48, 137, 1, 136, 184, 41, 42, 43, - 44, 45, 46, 47, 0, 49, 208, 133, 134, 208, - 163, 164, 0, 0, 0, 48, 0, 139, 181, 0, - 0, 50, 51, 52, 53, 54, 55, 0, 0, 209, - 205, 40, 178, 179, 180, 204, 0, 0, 0, 0, - 149, 0, 0, 0, 0, 0, 0, 0, 39, 182, - 183, 49, 152, 135, 56, 2, 3, 69, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 0, 0, 0, 0, 199, 0, 0, 68, - 87, 72, 200, 88, 175, 176, 177, 249, 207, 0, - 0, 0, 0, 162, 150, 140, 138, 130, 131, 0, - 0, 0, 0, 185, 89, 0, 0, 71, 94, 96, - 0, 0, 101, 95, 248, 0, 229, 0, 0, 0, - 0, 49, 217, 218, 6, 7, 8, 9, 10, 11, + 163, 0, 60, 149, 1, 148, 196, 53, 54, 55, + 56, 57, 58, 59, 0, 61, 220, 145, 146, 220, + 175, 176, 0, 0, 0, 60, 0, 151, 193, 0, + 0, 62, 63, 64, 65, 66, 67, 0, 0, 221, + 217, 52, 190, 191, 192, 216, 0, 0, 0, 0, + 161, 0, 0, 0, 0, 0, 0, 0, 51, 194, + 195, 61, 164, 147, 68, 2, 3, 81, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 0, 0, 0, 0, 211, 0, 0, 80, + 99, 84, 212, 100, 187, 188, 189, 261, 219, 0, + 0, 0, 0, 174, 162, 152, 150, 142, 143, 0, + 0, 0, 0, 197, 101, 0, 0, 83, 106, 108, + 0, 0, 113, 107, 260, 0, 241, 0, 0, 0, + 0, 61, 229, 230, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 0, 0, 0, 0, 0, 0, 0, 24, - 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 206, 49, 221, 0, 245, 157, 154, 153, - 155, 156, 158, 161, 0, 145, 147, 143, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, - 0, 0, 0, 141, 0, 0, 0, 93, 173, 100, - 98, 0, 0, 233, 228, 211, 210, 0, 0, 30, - 34, 29, 33, 28, 32, 27, 31, 35, 36, 0, - 0, 59, 59, 254, 0, 0, 243, 0, 0, 0, + 22, 23, 0, 0, 0, 0, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 0, 0, + 36, 37, 38, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 218, 61, 233, 0, 257, 169, + 166, 165, 167, 168, 170, 173, 0, 157, 159, 155, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 0, 0, 0, 0, 153, 0, 0, 0, 105, + 185, 112, 110, 0, 0, 245, 240, 223, 222, 0, + 0, 42, 46, 41, 45, 40, 44, 39, 43, 47, + 48, 0, 0, 71, 71, 266, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 159, 64, 64, 64, 115, 116, 4, - 5, 113, 114, 117, 112, 108, 109, 0, 0, 0, + 0, 0, 0, 0, 0, 171, 76, 76, 76, 127, + 128, 4, 5, 125, 126, 129, 124, 120, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 111, 110, 64, 70, 70, 97, 172, 166, 169, - 170, 0, 0, 90, 188, 189, 190, 195, 191, 192, - 193, 194, 186, 0, 197, 202, 201, 203, 0, 212, - 0, 0, 0, 250, 0, 252, 247, 0, 0, 0, + 0, 0, 0, 123, 122, 76, 82, 82, 109, 184, + 178, 181, 182, 0, 0, 102, 200, 201, 202, 207, + 203, 204, 205, 206, 198, 0, 209, 214, 213, 215, + 0, 224, 0, 0, 0, 262, 0, 264, 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 160, 0, 146, 148, 144, 0, - 0, 0, 0, 0, 0, 103, 129, 0, 0, 107, - 0, 104, 0, 0, 0, 0, 142, 91, 92, 165, - 167, 0, 62, 99, 187, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 257, 0, 0, 235, 0, 237, - 240, 0, 0, 238, 239, 0, 0, 0, 234, 0, - 255, 0, 0, 0, 66, 64, 247, 0, 0, 0, - 0, 0, 0, 102, 105, 106, 0, 0, 0, 0, - 171, 168, 63, 57, 0, 196, 0, 0, 227, 59, - 60, 59, 224, 246, 0, 0, 0, 0, 0, 230, - 231, 232, 227, 0, 61, 67, 65, 0, 0, 0, - 0, 0, 0, 128, 0, 0, 0, 0, 0, 174, - 0, 0, 0, 226, 0, 0, 251, 253, 0, 0, - 0, 236, 241, 242, 0, 256, 119, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 58, 198, 0, 0, - 0, 225, 222, 0, 244, 118, 0, 125, 0, 0, - 121, 122, 123, 124, 0, 215, 0, 0, 0, 223, - 0, 0, 0, 213, 0, 214, 0, 0, 120, 126, - 127, 0, 0, 0, 0, 0, 0, 220, 0, 0, - 219, 216 + 0, 0, 0, 0, 0, 0, 172, 0, 158, 160, + 156, 0, 0, 0, 0, 0, 115, 141, 0, 0, + 119, 0, 116, 0, 0, 0, 0, 0, 154, 103, + 104, 177, 179, 0, 74, 111, 199, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, + 249, 252, 0, 0, 250, 251, 0, 0, 0, 247, + 246, 0, 267, 0, 0, 0, 78, 76, 259, 0, + 0, 0, 0, 0, 114, 117, 118, 0, 0, 0, + 0, 0, 183, 180, 75, 69, 0, 208, 0, 0, + 239, 71, 72, 71, 236, 258, 0, 0, 0, 0, + 0, 242, 243, 244, 239, 0, 73, 79, 77, 0, + 0, 0, 0, 0, 140, 0, 0, 0, 0, 0, + 0, 186, 0, 0, 0, 238, 0, 0, 263, 265, + 0, 0, 0, 248, 253, 254, 0, 268, 131, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 210, + 0, 0, 0, 237, 234, 0, 256, 0, 137, 0, + 0, 133, 134, 135, 130, 136, 0, 227, 0, 0, + 0, 235, 0, 0, 0, 225, 0, 226, 0, 0, + 132, 138, 139, 0, 0, 0, 0, 0, 0, 232, + 0, 0, 231, 228 }; /* YYDEFGOTO[NTERM-NUM]. */ static const short int yydefgoto[] = { - -1, 86, 261, 277, 278, 279, 280, 199, 200, 229, - 201, 25, 15, 37, 449, 313, 394, 413, 336, 395, - 87, 88, 202, 90, 91, 120, 211, 346, 304, 347, - 109, 1, 2, 3, 283, 256, 254, 255, 63, 180, - 50, 104, 184, 92, 360, 289, 290, 291, 38, 96, - 16, 44, 17, 61, 18, 28, 365, 305, 93, 307, - 422, 19, 40, 41, 172, 497, 98, 236, 453, 454, - 173, 174, 374, 175, 176 + -1, 86, 273, 288, 289, 290, 291, 292, 211, 212, + 241, 213, 25, 15, 37, 461, 325, 406, 425, 348, + 407, 87, 88, 214, 90, 91, 120, 223, 357, 316, + 358, 109, 1, 2, 3, 295, 268, 266, 267, 63, + 192, 50, 104, 196, 92, 372, 301, 302, 303, 38, + 96, 16, 44, 17, 61, 18, 28, 377, 317, 93, + 319, 434, 19, 40, 41, 184, 509, 98, 248, 465, + 466, 185, 186, 386, 187, 188 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -463 +#define YYPACT_NINF -472 static const short int yypact[] = { - -463, 19, 202, 739, -463, -463, -463, -463, -463, -463, - -463, -463, -463, -463, -23, 340, 60, -463, -463, -12, - -463, -463, -8, 40, 115, 123, 66, -463, 67, 158, - 179, -463, -463, -463, -463, -463, -463, 1021, -14, -463, - -463, 120, -463, -463, -463, -463, 70, 71, 73, 77, - -463, 76, 158, 1021, 36, 36, 36, 36, -463, -463, - -463, 340, -463, -463, -463, -463, -463, 75, -463, -463, - -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, - -463, -463, 193, 194, 195, 577, -463, 120, 84, -463, - -463, -84, -463, -463, -463, -463, -463, 1197, -463, 180, - 31, 201, 183, 192, -463, -463, -463, -463, -463, 1062, - 1062, 1062, 1103, -463, -463, 100, 101, -463, -463, -84, - -91, 105, 853, -463, -463, 1062, -463, 164, 1144, 30, - 255, 340, -463, -463, -463, -463, -463, -463, -463, -463, - -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, - -463, -463, 1062, 1062, 1062, 1062, 1062, 1062, 1062, -463, - -463, -463, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, - 1062, 1062, -463, 340, -463, 51, -463, -463, -463, -463, - -463, -463, -463, -463, -74, -463, -463, -463, 125, 153, - 220, 155, 222, 159, 224, 171, 225, 223, 227, 175, - 228, 229, 420, -463, 1062, 1062, 1062, -463, 894, -463, - 116, 117, 645, -463, -463, 75, -463, 645, 645, -463, - -463, -463, -463, -463, -463, -463, -463, -463, -463, 645, - 1021, 140, 141, -463, 645, 138, 143, 226, 144, 146, - 148, 161, 162, 163, 166, 645, 645, 645, 177, 1021, - 1062, 1062, 249, -463, 182, 182, 182, -463, -463, -463, - -463, -463, -463, -463, -463, -463, -463, 178, 181, 184, - 185, 186, 187, 87, 1103, 597, 270, 188, 189, 197, - 199, -463, -463, 182, -36, -56, -84, -463, 120, -463, - 196, 200, 939, -463, -463, -463, -463, -463, -463, -463, - -463, -463, 236, 1103, -463, -463, -463, -463, 205, -463, - 210, 645, -9, -463, -3, -463, 211, 645, 191, 1062, - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 212, 216, 217, - 1062, 645, 645, 218, -463, -20, -463, -463, -463, 1103, - 1103, 1103, 1103, 1103, 1103, -463, -463, -50, -59, -463, - -31, -463, 1103, 1103, 1103, 1103, -463, -463, -463, -463, - -463, 980, 278, -463, -463, 293, 26, 313, 314, 230, - 645, 337, 645, 1062, -463, 231, 645, -463, 233, -463, - -463, 234, 237, -463, -463, 645, 645, 645, -463, 238, - -463, 1062, 332, 353, -463, 182, 211, 322, 246, 247, - 248, 250, 1103, -463, -463, -463, 251, 256, 257, 259, - -463, -463, -463, 307, 260, -463, 645, 645, 1062, 262, - -463, 262, -463, 263, 645, 265, 1062, 1062, 1062, -463, - -463, -463, 1062, 645, -463, -463, -463, 252, 1062, 1103, - 1103, 1103, 1103, -463, 1103, 1103, 1103, 1103, 378, -463, - 359, 273, 266, 263, 274, 339, -463, -463, 1062, 276, - 645, -463, -463, -463, 280, -463, -463, 281, 285, 284, - 296, 297, 295, 298, 299, 300, -463, -463, 393, 15, - 379, -463, -463, 301, -463, -463, 1103, -463, 1103, 1103, - -463, -463, -463, -463, 645, -463, 738, 65, 398, -463, - 302, 305, 306, -463, 312, -463, 738, 645, -463, -463, - -463, 407, 315, 355, 645, 408, 412, -463, 645, 645, - -463, -463 + -472, 24, 395, 501, -472, -472, -472, -472, -472, -472, + -472, -472, -472, -472, -13, 112, 46, -472, -472, -11, + -472, -472, -18, -41, 45, 51, -1, -472, 40, 106, + 131, -472, -472, -472, -472, -472, -472, 1136, -23, -472, + -472, 81, -472, -472, -472, -472, 30, 33, 49, 61, + -472, 57, 106, 1136, 78, 78, 78, 78, -472, -472, + -472, 112, -472, -472, -472, -472, -472, 62, -472, -472, + -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, + -472, -472, 185, 187, 188, 619, -472, 81, 67, -472, + -472, -71, -472, -472, -472, -472, -472, 1286, -472, 174, + 58, 196, 177, 178, -472, -472, -472, -472, -472, 1177, + 1177, 1177, 1197, -472, -472, 72, 73, -472, -472, -71, + -89, 79, 151, -472, -472, 1177, -472, 147, 1222, 12, + 218, 112, -472, -472, -472, -472, -472, -472, -472, -472, + -472, -472, -472, -472, -472, -472, -472, -472, -472, -472, + -472, -472, 1177, 1177, 1177, 1177, -472, -472, -472, -472, + -472, -472, -472, -472, -472, -472, -472, -472, 1177, 1177, + -472, -472, -472, 1177, 1177, 1177, 1177, 1177, 1177, 1177, + 1177, 1177, 1177, 1177, -472, 112, -472, -55, -472, -472, + -472, -472, -472, -472, -472, -472, -62, -472, -472, -472, + 95, 123, 204, 125, 205, 130, 206, 149, 207, 208, + 210, 181, 209, 214, 488, -472, 1177, 1177, 1177, -472, + 944, -472, 88, 93, 698, -472, -472, 62, -472, 698, + 698, -472, -472, -472, -472, -472, -472, -472, -472, -472, + -472, 698, 1136, 97, 110, -472, 698, 108, 113, 114, + 120, 121, 124, 126, 133, 136, 698, 698, 698, 213, + 139, 1136, 1177, 1177, 227, -472, 140, 140, 140, -472, + -472, -472, -472, -472, -472, -472, -472, -472, -472, 141, + 142, 143, 145, 146, 985, 1197, 639, 243, 148, 154, + 155, 157, 165, -472, -472, 140, -28, -51, -71, -472, + 81, -472, 153, 172, 1005, -472, -472, -472, -472, -472, + -472, -472, -472, -472, 244, 1197, -472, -472, -472, -472, + 180, -472, 182, 698, -7, -472, -6, -472, 183, 698, + 138, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 184, 186, + 189, 1177, 1177, 698, 698, 190, -472, -17, -472, -472, + -472, 1197, 1197, 1197, 1197, 1197, -472, -472, -24, -85, + -472, -80, -472, 1197, 1197, 1197, 1197, 1197, -472, -472, + -472, -472, -472, 1046, 277, -472, -472, 289, -27, 293, + 296, 191, 698, 314, 698, 1177, -472, 194, 698, 195, + -472, -472, 200, 201, -472, -472, 698, 698, 698, -472, + -472, 202, -472, 1177, 298, 324, -472, 140, 183, 203, + 211, 212, 224, 1197, -472, -472, -472, 225, 226, 230, + 295, 232, -472, -472, -472, 275, 233, -472, 698, 698, + 1177, 235, -472, 235, -472, 239, 698, 241, 1177, 1177, + 1177, -472, -472, -472, 1177, 698, -472, -472, -472, 215, + 1197, 1197, 1197, 1197, -472, 1197, 1197, 1197, 1177, 1197, + 329, -472, 310, 242, 223, 239, 240, 278, -472, -472, + 1177, 238, 698, -472, -472, -472, 247, -472, -472, 245, + 250, 246, 255, 254, 256, 257, 259, 262, -472, -472, + 318, 15, 337, -472, -472, 252, -472, 1197, -472, 1197, + 1197, -472, -472, -472, -472, -472, 698, -472, 818, 65, + 371, -472, 265, 267, 268, -472, 272, -472, 818, 698, + -472, -472, -472, 378, 274, 328, 698, 384, 385, -472, + 698, 698, -472, -472 }; /* YYPGOTO[NTERM-NUM]. */ static const short int yypgoto[] = { - -463, -463, -463, 338, 342, 343, 344, -129, -128, -462, - -463, 395, 418, -118, -463, -225, 89, -463, -247, -463, - -49, -463, -37, -463, -82, 323, -463, -102, 253, -253, - 83, -463, -463, -463, -463, -463, -463, -463, 400, -463, - -463, -463, -463, 2, -463, 92, -463, -463, 399, -463, - -463, -463, -463, -463, 451, -463, -463, -359, -57, 62, - -105, -463, 437, -463, -463, -463, -463, -463, 90, 32, - -463, -463, 69, -463, -463 + -472, -472, -472, 311, 312, 313, 315, 317, -129, -127, + -471, -472, 370, 392, -120, -472, -237, 50, -472, -253, + -472, -49, -472, -37, -472, -67, 301, -472, -110, 220, + -263, 64, -472, -472, -472, -472, -472, -472, -472, 373, + -472, -472, -472, -472, 2, -472, 70, -472, -472, 374, + -472, -472, -472, -472, -472, 441, -472, -472, -418, 34, + 31, -115, -472, 426, -472, -472, -472, -472, -472, 63, + 3, -472, -472, 38, -472, -472 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -133 +#define YYTABLE_NINF -145 static const short int yytable[] = { - 89, 227, 228, 119, 106, 26, 370, 315, 337, 338, - 203, 39, 372, 230, 392, 94, 89, 496, 42, 4, - 213, 348, 350, 216, 206, 219, 220, 221, 222, 223, - 224, 225, 226, -70, 207, 506, 356, 393, 29, 217, - 119, 252, 123, 26, 46, 47, 48, 253, 371, 233, - 366, 218, 237, 238, 371, 249, 402, 239, 240, 241, - 242, 243, 244, 49, 404, 402, 248, 358, 107, 108, - 123, 403, 185, 186, 187, 219, 220, 221, 222, 223, - 224, 225, 226, 39, 402, 357, 178, 179, 212, 121, - 123, 212, 65, 66, 405, 117, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 79, 80, 20, - 95, 21, 59, 43, 60, 231, 232, 212, 234, 235, - 212, 212, 284, 285, 286, 212, 212, 212, 212, 212, - 212, 245, 246, 247, 212, 81, 495, 504, 110, 111, - 112, 402, 20, 53, 21, 282, 333, 512, 436, 415, - 250, 251, 257, 258, 51, 306, -30, -30, -29, -29, - 306, 306, -28, -28, 7, 8, 9, 10, 54, 12, - 55, 288, 306, 56, -27, -27, 52, 306, 259, 260, - 58, 311, 62, 64, 99, 100, 505, 101, 306, 306, - 306, 102, -71, 89, 456, 103, 457, 114, 115, 116, - 331, 122, -132, 82, 177, 181, 83, 182, 345, 84, - 286, 85, 89, 332, 212, 378, 183, 380, 381, 382, - 204, 205, 208, 214, -34, 388, -33, 5, -32, -31, - -37, 292, 262, 6, -38, 293, 263, 396, 397, 398, - 399, 400, 401, 7, 8, 9, 10, 11, 12, 13, - 406, 407, 408, 409, 306, 312, 314, 317, 318, 320, - 306, 321, 319, 322, 14, 219, 220, 221, 222, 223, - 224, 225, 226, 334, 306, 306, 323, 324, 325, 308, - 309, 326, 377, 212, 379, 212, 212, 212, 383, 384, - 359, 310, 330, 212, 351, 339, 316, 335, 340, 364, - 443, 341, 342, 343, 344, 352, 353, 327, 328, 329, - 376, 361, 392, 306, 354, 306, 355, 414, 362, 306, - 367, 461, 462, 463, 288, 368, 373, 385, 306, 306, - 306, 386, 387, 391, 416, 417, 212, 468, 469, 470, - 471, 420, 472, 473, 474, 475, 424, 418, 426, 427, - 227, 228, 428, 481, 433, 432, 434, 435, 438, 306, - 306, 439, 440, 441, 448, 442, 444, 306, 227, 228, - 466, 445, 446, 369, 447, 450, 306, 455, 458, 375, - 460, 212, 476, 477, 500, 479, 501, 502, 478, 212, - 212, 212, 480, 389, 390, 212, 371, 482, 484, 485, - 486, 467, 487, 306, 30, 31, 32, 33, 34, 35, - 36, 488, 489, 490, 494, 498, 491, 492, 493, 507, - 508, 212, 499, 509, 510, 65, 66, 511, 514, 518, - 515, 516, 419, 519, 421, 168, 97, 306, 425, 169, - 170, 171, 20, 57, 21, 210, 264, 429, 430, 431, - 306, 412, 105, 411, 27, 281, 45, 306, 265, 266, - 113, 306, 306, 423, 464, 437, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 451, 452, - 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, - 0, 0, 0, 0, 0, 465, 0, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 0, 0, 0, 0, - 0, 267, 483, 268, 269, 159, 160, 161, 0, 270, - 271, 272, 0, 0, 0, 0, 0, 0, 0, 273, - 0, 0, 274, 0, 275, 0, 0, 276, 0, 0, - 0, 0, 0, 0, 0, 0, 503, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 513, - 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, - 520, 521, 65, 66, 0, 117, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 20, - 0, 21, 65, 66, 0, 117, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 79, 80, 20, - 0, 21, 0, 0, 0, 81, 0, 0, 0, 0, + 89, 239, 215, 240, 106, 26, 94, 327, 382, 384, + 225, 242, 39, 228, 349, 350, 89, 404, 119, 42, + 508, 229, 359, 361, 4, 231, 232, 233, 234, 235, + 236, 237, 238, 230, 46, 47, 48, 218, 518, 245, + 405, 413, 368, 26, 262, 263, 413, 219, 29, 415, + 383, 383, 378, 49, 249, 119, 416, -82, 250, 251, + 252, 253, 254, 255, 264, 261, 123, 259, 260, 39, + 265, 53, 197, 198, 199, 231, 232, 233, 234, 235, + 236, 237, 238, 370, 51, 59, 123, 60, 224, 121, + 516, 224, 7, 8, 9, 10, 54, 12, 55, 413, + 524, 56, 413, 20, 369, 21, 52, 427, 414, 123, + 107, 108, 95, 190, 191, 243, 244, 224, 246, 110, + 111, 112, 269, 270, 58, 43, -42, -42, -41, -41, + 62, 247, 224, -40, -40, 64, 224, 224, 224, 224, + 224, 224, 256, 257, 258, 224, 224, 507, 345, 296, + 297, 298, -39, -39, 448, 99, 65, 66, 100, 117, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 20, 101, 21, 30, 31, 32, 33, + 34, 35, 36, 300, 271, 272, 102, 103, 221, 114, + -83, 115, 116, 323, 468, 122, 469, 517, 189, 81, + 193, 194, 195, 216, 217, 89, 226, 220, -46, -45, + -44, -43, 343, 274, 304, -49, 389, -50, 391, 392, + 393, 275, 305, 324, 89, 344, 224, 400, 231, 232, + 233, 234, 235, 236, 237, 238, 326, 298, 329, 330, + 331, 408, 409, 410, 411, 412, 332, 333, 294, 341, + 334, 346, 335, 417, 418, 419, 420, 421, 318, 336, + 320, 321, 337, 318, 318, 342, 347, 362, 388, 351, + 352, 353, 322, 354, 355, 318, 363, 328, 82, 373, + 318, 83, 364, 365, 84, 366, 85, 338, 339, 340, + 318, 318, 318, 367, 224, 390, 224, 224, 224, 394, + 395, 374, 371, 454, 399, 224, 379, 376, 380, 385, + 396, 404, 397, 426, 428, 398, 403, 429, 432, 430, + 436, 438, 446, 473, 474, 475, 439, 440, 447, 450, + 444, 458, 460, 488, 489, 383, 300, 451, 452, 506, + 479, 480, 481, 482, 478, 483, 484, 485, 224, 487, + 453, 455, 456, 491, 381, 493, 457, 318, 459, 462, + 387, 467, 239, 318, 240, 470, 445, 472, 490, 492, + 494, 497, 499, 510, 401, 402, 496, 318, 318, 498, + 239, 500, 240, 501, 511, 502, 503, 512, 504, 513, + 514, 505, 519, 224, 520, -144, 521, 522, 523, 526, + 527, 224, 224, 224, 528, 530, 531, 224, 179, 180, + 181, 97, 182, 431, 183, 433, 318, 57, 318, 437, + 5, 486, 318, 222, 424, 105, 6, 441, 442, 443, + 318, 318, 318, 224, 293, 113, 7, 8, 9, 10, + 11, 12, 13, 423, 27, 45, 449, 476, 435, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 463, + 464, 0, 318, 318, 0, 0, 0, 471, 0, 0, + 318, 0, 0, 0, 0, 0, 477, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 81, 0, 0, 294, 295, - 65, 66, 296, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, - 0, 297, 298, 299, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, - 0, 0, 0, 82, 0, 0, 83, 0, 0, 84, - 0, 85, 118, 0, 0, 0, 302, 0, 0, 0, - 0, 0, 0, 82, 0, 0, 83, 0, 0, 84, - 0, 85, 349, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 294, 295, 0, 0, 296, 267, 0, 268, 269, - 159, 160, 161, 0, 270, 271, 272, 0, 0, -40, - 0, 20, 0, 21, 297, 298, 299, 303, 0, 0, - 6, -40, -40, 0, 0, 0, 300, 301, 0, 0, - -40, -40, -40, -40, -40, -40, -40, 0, 0, -40, - 22, 0, 0, 0, 0, 0, 0, 23, 0, 302, - 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 134, 135, 136, 137, + 0, 0, 0, 65, 66, 0, 0, 0, 0, 0, + 0, 0, 0, 495, 0, 0, 318, 0, 0, 0, + 20, 0, 21, 0, 276, 0, 0, 0, 0, 0, + 0, -52, 0, 20, 0, 21, 277, 278, 0, 0, + 0, 0, 6, -52, -52, 0, 0, 515, 0, 0, + 318, 0, -52, -52, -52, -52, -52, -52, -52, 0, + 525, -52, 22, 318, 0, 0, 0, 529, 0, 23, + 318, 532, 533, 24, 318, 318, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 0, 0, 0, 0, 0, 267, - 0, 268, 269, 159, 160, 161, 0, 270, 271, 272, - 0, 0, 0, 0, 0, 0, 0, 0, 65, 66, - 303, 117, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 20, 0, 21, 0, 0, + 148, 149, 150, 151, 0, 0, 0, 0, 0, 279, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 0, 280, 170, 171, 172, 0, 281, 282, + 283, 0, 0, 0, 0, 0, 0, 0, 284, 0, + 0, 285, 0, 286, 65, 66, 287, 117, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 20, 0, 21, 65, 66, 0, 117, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 79, + 80, 20, 0, 21, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 209, 0, 0, 0, 0, 0, 0, 0, 0, 65, - 66, 81, 117, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 20, 0, 21, 0, + 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 81, 0, 65, 66, 0, 117, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 20, 0, 21, 0, 0, 0, 0, 0, 82, - 0, 0, 83, 0, 0, 84, 363, 85, 0, 0, - 0, 0, 0, 0, 0, 65, 66, 81, 117, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 20, 0, 21, 0, 0, 0, 0, 0, - 82, 0, 0, 83, 0, 0, 84, 410, 85, 0, - 0, 0, 0, 0, 0, 0, 65, 66, 81, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 20, 0, 21, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 82, 0, 0, 83, 0, - 0, 84, 0, 85, 0, 0, 0, 65, 66, 81, - 117, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 20, 0, 21, 0, 0, 0, + 0, 306, 307, 65, 66, 308, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 20, 0, 21, 0, 309, 310, 311, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 312, 313, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 83, - 0, 0, 84, 0, 85, 0, 0, 0, 65, 66, - 81, 117, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 79, 80, 20, 0, 21, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, - 83, 0, 0, 84, 0, 85, 0, 0, 0, 65, - 66, 81, 215, 68, 69, 70, 71, 72, 73, 74, + 0, 0, 84, 0, 85, 118, 0, 0, 0, 314, + 0, 0, 0, 0, 0, 0, 82, 0, 0, 83, + 0, 0, 84, 0, 85, 360, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 0, 0, 0, 0, 0, 279, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 0, 280, 170, 171, 172, 0, 281, 282, + 283, 306, 307, 0, 0, 308, 0, 0, 0, 0, + 0, 315, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 309, 310, 311, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 312, 313, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 314, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 0, 0, 0, 0, 0, 279, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 0, 280, 170, 171, 172, 0, 281, 282, + 283, 0, 0, 0, 0, 0, 0, 0, 0, 65, + 66, 315, 117, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 20, 0, 21, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, - 0, 83, 0, 0, 84, 0, 85, 0, 0, 0, - 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, - 0, 0, 83, 0, 0, 84, 0, 85, 0, 0, - 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 126, 127, 0, 0, - 82, 0, 0, 83, 0, 0, 84, 0, 85, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 0, 0, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167 + 0, 299, 0, 0, 0, 0, 0, 0, 0, 0, + 65, 66, 81, 117, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 79, 80, 20, 0, 21, + 65, 66, 0, 117, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 20, 0, 21, + 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, + 0, 0, 375, 0, 0, 0, 0, 0, 0, 0, + 0, 65, 66, 81, 117, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 20, 0, + 21, 82, 0, 0, 83, 0, 0, 84, 0, 85, + 0, 0, 0, 422, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 0, 0, 83, 0, 356, 84, 0, + 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 0, 0, 83, 0, 0, 84, 0, + 85, 65, 66, 0, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 20, 0, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 0, 0, 83, 0, 0, 84, + 0, 85, 65, 66, 81, 117, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 20, + 0, 21, 65, 66, 0, 117, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 79, 80, 20, + 0, 21, 0, 0, 0, 81, 0, 65, 66, 0, + 227, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 20, 81, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 0, 0, 83, 0, 0, 84, + 81, 85, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 0, 0, 83, 0, 0, + 84, 0, 85, 0, 0, 0, 0, 0, 0, 0, + 0, 124, 0, 0, 82, 0, 0, 83, 0, 0, + 84, 0, 85, 0, 0, 125, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 126, 127, 0, 0, 82, + 0, 0, 83, 0, 0, 84, 0, 85, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 0, 0, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178 }; static const short int yycheck[] = { - 37, 130, 130, 85, 53, 3, 15, 232, 255, 256, - 112, 23, 15, 131, 34, 29, 53, 479, 30, 0, - 125, 274, 275, 128, 115, 10, 11, 12, 13, 14, - 15, 16, 17, 117, 125, 497, 283, 57, 61, 9, - 122, 115, 126, 41, 52, 53, 54, 121, 57, 154, - 303, 21, 157, 158, 57, 173, 115, 162, 163, 164, - 165, 166, 167, 71, 123, 115, 171, 123, 32, 33, - 126, 121, 109, 110, 111, 10, 11, 12, 13, 14, - 15, 16, 17, 23, 115, 121, 55, 56, 125, 87, - 126, 128, 5, 6, 125, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 124, 24, 45, 125, 47, 152, 153, 154, 155, 156, - 157, 158, 204, 205, 206, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 48, 121, 496, 55, 56, - 57, 115, 22, 20, 24, 202, 251, 506, 395, 123, - 99, 100, 27, 28, 114, 212, 3, 4, 3, 4, - 217, 218, 3, 4, 41, 42, 43, 44, 45, 46, - 47, 208, 229, 50, 3, 4, 61, 234, 3, 4, - 114, 230, 24, 4, 114, 114, 121, 114, 245, 246, - 247, 114, 117, 230, 419, 119, 421, 4, 4, 4, - 249, 117, 0, 116, 24, 4, 119, 24, 121, 122, - 292, 124, 249, 250, 251, 320, 24, 322, 323, 324, - 120, 120, 117, 59, 4, 330, 4, 25, 4, 4, - 7, 115, 4, 31, 7, 118, 7, 339, 340, 341, - 342, 343, 344, 41, 42, 43, 44, 45, 46, 47, - 352, 353, 354, 355, 311, 115, 115, 119, 115, 115, - 317, 115, 36, 115, 62, 10, 11, 12, 13, 14, - 15, 16, 17, 24, 331, 332, 115, 115, 115, 217, - 218, 115, 319, 320, 321, 322, 323, 324, 325, 326, - 288, 229, 115, 330, 24, 117, 234, 115, 117, 63, - 402, 117, 117, 117, 117, 117, 117, 245, 246, 247, - 119, 115, 34, 370, 117, 372, 117, 24, 118, 376, - 115, 426, 427, 428, 361, 115, 115, 115, 385, 386, - 387, 115, 115, 115, 21, 21, 373, 439, 440, 441, - 442, 4, 444, 445, 446, 447, 115, 117, 115, 115, - 479, 479, 115, 458, 391, 117, 24, 4, 36, 416, - 417, 115, 115, 115, 57, 115, 115, 424, 497, 497, - 118, 115, 115, 311, 115, 115, 433, 115, 115, 317, - 115, 418, 4, 24, 486, 119, 488, 489, 115, 426, - 427, 428, 118, 331, 332, 432, 57, 121, 118, 118, - 115, 438, 118, 460, 64, 65, 66, 67, 68, 69, - 70, 115, 115, 118, 21, 36, 118, 118, 118, 21, - 118, 458, 121, 118, 118, 5, 6, 115, 21, 21, - 115, 76, 370, 21, 372, 97, 41, 494, 376, 97, - 97, 97, 22, 25, 24, 122, 26, 385, 386, 387, - 507, 362, 52, 361, 3, 202, 19, 514, 38, 39, - 61, 518, 519, 373, 432, 396, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 416, 417, - -1, -1, -1, -1, -1, -1, 424, -1, -1, -1, - -1, -1, -1, -1, -1, 433, -1, -1, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, -1, -1, -1, -1, - -1, 101, 460, 103, 104, 105, 106, 107, -1, 109, - 110, 111, -1, -1, -1, -1, -1, -1, -1, 119, - -1, -1, 122, -1, 124, -1, -1, 127, -1, -1, - -1, -1, -1, -1, -1, -1, 494, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 507, - -1, -1, -1, -1, -1, -1, 514, -1, -1, -1, - 518, 519, 5, 6, -1, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - -1, 24, 5, 6, -1, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - -1, 24, -1, -1, -1, 48, -1, -1, -1, -1, + 37, 130, 112, 130, 53, 3, 29, 244, 15, 15, + 125, 131, 23, 128, 267, 268, 53, 34, 85, 30, + 491, 9, 285, 286, 0, 10, 11, 12, 13, 14, + 15, 16, 17, 21, 52, 53, 54, 126, 509, 154, + 57, 126, 295, 41, 99, 100, 126, 136, 61, 134, + 57, 57, 315, 71, 169, 122, 136, 128, 173, 174, + 175, 176, 177, 178, 126, 185, 137, 182, 183, 23, + 132, 20, 109, 110, 111, 10, 11, 12, 13, 14, + 15, 16, 17, 134, 125, 45, 137, 47, 125, 87, + 508, 128, 41, 42, 43, 44, 45, 46, 47, 126, + 518, 50, 126, 22, 132, 24, 61, 134, 132, 137, + 32, 33, 135, 55, 56, 152, 153, 154, 155, 55, + 56, 57, 27, 28, 125, 136, 3, 4, 3, 4, + 24, 168, 169, 3, 4, 4, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 132, 263, 216, + 217, 218, 3, 4, 407, 125, 5, 6, 125, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 125, 24, 64, 65, 66, 67, + 68, 69, 70, 220, 3, 4, 125, 130, 37, 4, + 128, 4, 4, 242, 431, 128, 433, 132, 24, 48, + 4, 24, 24, 131, 131, 242, 59, 128, 4, 4, + 4, 4, 261, 4, 126, 7, 331, 7, 333, 334, + 335, 7, 129, 126, 261, 262, 263, 342, 10, 11, + 12, 13, 14, 15, 16, 17, 126, 304, 130, 126, + 126, 351, 352, 353, 354, 355, 126, 126, 214, 36, + 126, 24, 126, 363, 364, 365, 366, 367, 224, 126, + 229, 230, 126, 229, 230, 126, 126, 24, 130, 128, + 128, 128, 241, 128, 128, 241, 128, 246, 127, 126, + 246, 130, 128, 128, 133, 128, 135, 256, 257, 258, + 256, 257, 258, 128, 331, 332, 333, 334, 335, 336, + 337, 129, 300, 413, 341, 342, 126, 63, 126, 126, + 126, 34, 126, 24, 21, 126, 126, 21, 4, 128, + 126, 126, 24, 438, 439, 440, 126, 126, 4, 126, + 128, 36, 57, 4, 24, 57, 373, 126, 126, 21, + 450, 451, 452, 453, 129, 455, 456, 457, 385, 459, + 126, 126, 126, 130, 323, 470, 126, 323, 126, 126, + 329, 126, 491, 329, 491, 126, 403, 126, 126, 129, + 132, 126, 126, 36, 343, 344, 129, 343, 344, 129, + 509, 126, 509, 129, 132, 129, 129, 497, 129, 499, + 500, 129, 21, 430, 129, 0, 129, 129, 126, 21, + 126, 438, 439, 440, 76, 21, 21, 444, 97, 97, + 97, 41, 97, 382, 97, 384, 382, 25, 384, 388, + 25, 458, 388, 122, 374, 52, 31, 396, 397, 398, + 396, 397, 398, 470, 214, 61, 41, 42, 43, 44, + 45, 46, 47, 373, 3, 19, 408, 444, 385, -1, + -1, -1, -1, -1, -1, -1, -1, 62, -1, 428, + 429, -1, 428, 429, -1, -1, -1, 436, -1, -1, + 436, -1, -1, -1, -1, -1, 445, -1, -1, 445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 48, -1, -1, 3, 4, - 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 22, -1, 24, - -1, 26, 27, 28, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 38, 39, -1, -1, -1, -1, -1, - -1, -1, -1, 116, -1, -1, 119, -1, -1, 122, - -1, 124, 125, -1, -1, -1, 61, -1, -1, -1, - -1, -1, -1, 116, -1, -1, 119, -1, -1, 122, - -1, 124, 125, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 3, 4, -1, -1, 7, 101, -1, 103, 104, - 105, 106, 107, -1, 109, 110, 111, -1, -1, 20, - -1, 22, -1, 24, 26, 27, 28, 122, -1, -1, - 31, 32, 33, -1, -1, -1, 38, 39, -1, -1, - 41, 42, 43, 44, 45, 46, 47, -1, -1, 50, - 51, -1, -1, -1, -1, -1, -1, 58, -1, 61, - -1, 62, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, 81, + -1, -1, -1, 5, 6, -1, -1, -1, -1, -1, + -1, -1, -1, 472, -1, -1, 472, -1, -1, -1, + 22, -1, 24, -1, 26, -1, -1, -1, -1, -1, + -1, 20, -1, 22, -1, 24, 38, 39, -1, -1, + -1, -1, 31, 32, 33, -1, -1, 506, -1, -1, + 506, -1, 41, 42, 43, 44, 45, 46, 47, -1, + 519, 50, 51, 519, -1, -1, -1, 526, -1, 58, + 526, 530, 531, 62, 530, 531, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -1, -1, -1, -1, -1, 101, - -1, 103, 104, 105, 106, 107, -1, 109, 110, 111, - -1, -1, -1, -1, -1, -1, -1, -1, 5, 6, - 122, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, -1, 24, -1, -1, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, -1, 115, 116, 117, 118, -1, 120, 121, + 122, -1, -1, -1, -1, -1, -1, -1, 130, -1, + -1, 133, -1, 135, 5, 6, 138, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, -1, 24, 5, 6, -1, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, -1, 24, -1, -1, -1, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 37, -1, -1, -1, -1, -1, -1, -1, -1, 5, - 6, 48, 8, 9, 10, 11, 12, 13, 14, 15, + -1, -1, -1, -1, -1, -1, -1, 48, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3, 4, 5, 6, 7, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 22, -1, 24, -1, 26, 27, 28, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, -1, + -1, -1, -1, -1, -1, -1, 127, -1, -1, 130, + -1, -1, 133, -1, 135, 136, -1, -1, -1, 61, + -1, -1, -1, -1, -1, -1, 127, -1, -1, 130, + -1, -1, 133, -1, 135, 136, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, -1, -1, -1, -1, -1, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, -1, 115, 116, 117, 118, -1, 120, 121, + 122, 3, 4, -1, -1, 7, -1, -1, -1, -1, + -1, 133, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 26, 27, 28, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 38, 39, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, -1, -1, -1, -1, -1, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, -1, 115, 116, 117, 118, -1, 120, 121, + 122, -1, -1, -1, -1, -1, -1, -1, -1, 5, + 6, 133, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 48, -1, 5, 6, -1, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, -1, 24, -1, -1, -1, -1, -1, 116, - -1, -1, 119, -1, -1, 122, 37, 124, -1, -1, - -1, -1, -1, -1, -1, 5, 6, 48, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, -1, 24, -1, -1, -1, -1, -1, - 116, -1, -1, 119, -1, -1, 122, 37, 124, -1, - -1, -1, -1, -1, -1, -1, 5, 6, 48, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, -1, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 116, -1, -1, 119, -1, - -1, 122, -1, 124, -1, -1, -1, 5, 6, 48, + 5, 6, 48, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, -1, 24, + 5, 6, -1, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, -1, 24, + -1, -1, -1, 48, -1, -1, -1, -1, -1, -1, + -1, -1, 37, -1, -1, -1, -1, -1, -1, -1, + -1, 5, 6, 48, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, + 24, 127, -1, -1, 130, -1, -1, 133, -1, 135, + -1, -1, -1, 37, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 48, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 127, -1, -1, 130, -1, 132, 133, -1, + 135, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 127, -1, -1, 130, -1, -1, 133, -1, + 135, 5, 6, -1, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, + 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 127, -1, -1, 130, -1, -1, 133, + -1, 135, 5, 6, 48, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + -1, 24, 5, 6, -1, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + -1, 24, -1, -1, -1, 48, -1, 5, 6, -1, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, -1, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 116, -1, -1, 119, - -1, -1, 122, -1, 124, -1, -1, -1, 5, 6, - 48, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, -1, 24, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 116, -1, -1, - 119, -1, -1, 122, -1, 124, -1, -1, -1, 5, - 6, 48, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, -1, 24, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 116, -1, - -1, 119, -1, -1, 122, -1, 124, -1, -1, -1, - -1, -1, 48, -1, -1, -1, -1, -1, -1, -1, + 18, 19, 20, 21, 22, 48, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 116, - -1, -1, 119, -1, -1, 122, -1, 124, -1, -1, - -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 49, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 59, 60, -1, -1, - 116, -1, -1, 119, -1, -1, 122, -1, 124, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, -1, -1, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113 + -1, -1, -1, 127, -1, -1, 130, -1, -1, 133, + 48, 135, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 127, -1, -1, 130, -1, -1, + 133, -1, 135, -1, -1, -1, -1, -1, -1, -1, + -1, 35, -1, -1, 127, -1, -1, 130, -1, -1, + 133, -1, 135, -1, -1, 49, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 59, 60, -1, -1, 127, + -1, -1, 130, -1, -1, 133, -1, 135, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, -1, -1, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const unsigned char yystos[] = { - 0, 159, 160, 161, 0, 25, 31, 41, 42, 43, - 44, 45, 46, 47, 62, 140, 178, 180, 182, 189, - 22, 24, 51, 58, 62, 139, 171, 182, 183, 61, - 64, 65, 66, 67, 68, 69, 70, 141, 176, 23, - 190, 191, 30, 125, 179, 190, 52, 53, 54, 71, - 168, 114, 61, 20, 45, 47, 50, 140, 114, 45, - 47, 181, 24, 166, 4, 5, 6, 8, 9, 10, + 0, 171, 172, 173, 0, 25, 31, 41, 42, 43, + 44, 45, 46, 47, 62, 152, 190, 192, 194, 201, + 22, 24, 51, 58, 62, 151, 183, 194, 195, 61, + 64, 65, 66, 67, 68, 69, 70, 153, 188, 23, + 202, 203, 30, 136, 191, 202, 52, 53, 54, 71, + 180, 125, 61, 20, 45, 47, 50, 152, 125, 45, + 47, 193, 24, 178, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 48, 116, 119, 122, 124, 129, 148, 149, 150, - 151, 152, 171, 186, 29, 124, 177, 139, 194, 114, - 114, 114, 114, 119, 169, 166, 148, 32, 33, 158, - 158, 158, 158, 176, 4, 4, 4, 8, 125, 152, - 153, 171, 117, 126, 35, 49, 59, 60, 72, 73, + 21, 48, 127, 130, 133, 135, 140, 160, 161, 162, + 163, 164, 183, 198, 29, 135, 189, 151, 206, 125, + 125, 125, 125, 130, 181, 178, 160, 32, 33, 170, + 170, 170, 170, 188, 4, 4, 4, 8, 136, 164, + 165, 183, 128, 137, 35, 49, 59, 60, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 131, 132, - 133, 134, 192, 198, 199, 201, 202, 24, 55, 56, - 167, 4, 24, 24, 170, 150, 150, 150, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 135, - 136, 138, 150, 155, 120, 120, 115, 125, 117, 37, - 153, 154, 150, 188, 59, 8, 188, 9, 21, 10, - 11, 12, 13, 14, 15, 16, 17, 135, 136, 137, - 141, 150, 150, 188, 150, 150, 195, 188, 188, 188, - 188, 188, 188, 188, 188, 150, 150, 150, 188, 141, - 99, 100, 115, 121, 164, 165, 163, 27, 28, 3, - 4, 130, 4, 7, 26, 38, 39, 101, 103, 104, - 109, 110, 111, 119, 122, 124, 127, 131, 132, 133, - 134, 156, 186, 162, 152, 152, 152, 37, 150, 173, - 174, 175, 115, 118, 3, 4, 7, 26, 27, 28, - 38, 39, 61, 122, 156, 185, 186, 187, 187, 187, - 187, 148, 115, 143, 115, 143, 187, 119, 115, 36, - 115, 115, 115, 115, 115, 115, 115, 187, 187, 187, - 115, 148, 150, 188, 24, 115, 146, 146, 146, 117, - 117, 117, 117, 117, 117, 121, 155, 157, 157, 125, - 157, 24, 117, 117, 117, 117, 146, 121, 123, 171, - 172, 115, 118, 37, 63, 184, 157, 115, 115, 187, - 15, 57, 15, 115, 200, 187, 119, 150, 188, 150, - 188, 188, 188, 150, 150, 115, 115, 115, 188, 187, - 187, 115, 34, 57, 144, 147, 155, 155, 155, 155, - 155, 155, 115, 121, 123, 125, 155, 155, 155, 155, - 37, 173, 144, 145, 24, 123, 21, 21, 117, 187, - 4, 187, 188, 196, 115, 187, 115, 115, 115, 187, - 187, 187, 117, 150, 24, 4, 146, 200, 36, 115, - 115, 115, 115, 155, 115, 115, 115, 115, 57, 142, - 115, 187, 187, 196, 197, 115, 143, 143, 115, 187, - 115, 188, 188, 188, 197, 187, 118, 150, 155, 155, - 155, 155, 155, 155, 155, 155, 4, 24, 115, 119, - 118, 188, 121, 187, 118, 118, 115, 118, 115, 115, - 118, 118, 118, 118, 21, 121, 137, 193, 36, 121, - 155, 155, 155, 187, 185, 121, 137, 21, 118, 118, - 118, 115, 185, 187, 21, 115, 76, 187, 21, 21, - 187, 187 + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 142, + 143, 144, 145, 146, 204, 210, 211, 213, 214, 24, + 55, 56, 179, 4, 24, 24, 182, 162, 162, 162, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 147, 148, 150, 162, 167, 131, 131, 126, 136, + 128, 37, 165, 166, 162, 200, 59, 8, 200, 9, + 21, 10, 11, 12, 13, 14, 15, 16, 17, 147, + 148, 149, 153, 162, 162, 200, 162, 162, 207, 200, + 200, 200, 200, 200, 200, 200, 162, 162, 162, 200, + 200, 153, 99, 100, 126, 132, 176, 177, 175, 27, + 28, 3, 4, 141, 4, 7, 26, 38, 39, 101, + 115, 120, 121, 122, 130, 133, 135, 138, 142, 143, + 144, 145, 146, 168, 198, 174, 164, 164, 164, 37, + 162, 185, 186, 187, 126, 129, 3, 4, 7, 26, + 27, 28, 38, 39, 61, 133, 168, 197, 198, 199, + 199, 199, 199, 160, 126, 155, 126, 155, 199, 130, + 126, 126, 126, 126, 126, 126, 126, 126, 199, 199, + 199, 36, 126, 160, 162, 200, 24, 126, 158, 158, + 158, 128, 128, 128, 128, 128, 132, 167, 169, 169, + 136, 169, 24, 128, 128, 128, 128, 128, 158, 132, + 134, 183, 184, 126, 129, 37, 63, 196, 169, 126, + 126, 199, 15, 57, 15, 126, 212, 199, 130, 200, + 162, 200, 200, 200, 162, 162, 126, 126, 126, 162, + 200, 199, 199, 126, 34, 57, 156, 159, 167, 167, + 167, 167, 167, 126, 132, 134, 136, 167, 167, 167, + 167, 167, 37, 185, 156, 157, 24, 134, 21, 21, + 128, 199, 4, 199, 200, 208, 126, 199, 126, 126, + 126, 199, 199, 199, 128, 162, 24, 4, 158, 212, + 126, 126, 126, 126, 167, 126, 126, 126, 36, 126, + 57, 154, 126, 199, 199, 208, 209, 126, 155, 155, + 126, 199, 126, 200, 200, 200, 209, 199, 129, 167, + 167, 167, 167, 167, 167, 167, 162, 167, 4, 24, + 126, 130, 129, 200, 132, 199, 129, 126, 129, 126, + 126, 129, 129, 129, 129, 129, 21, 132, 149, 205, + 36, 132, 167, 167, 167, 199, 197, 132, 149, 21, + 129, 129, 129, 126, 197, 199, 21, 126, 76, 199, + 21, 21, 199, 199 }; #define yyerrok (yyerrstatus = 0) @@ -3032,7 +3088,7 @@ yyreduce: switch (yyn) { case 3: -#line 1164 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" +#line 1169 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[0].UIntVal) > (uint32_t)INT32_MAX) // Outside of my range! GEN_ERROR("Value too large for type!"); @@ -3042,7 +3098,7 @@ yyreduce: break; case 5: -#line 1173 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" +#line 1178 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[0].UInt64Val) > (uint64_t)INT64_MAX) // Outside of my range! GEN_ERROR("Value too large for type!"); @@ -3051,99 +3107,99 @@ yyreduce: ;} break; - case 39: -#line 1197 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 51: +#line 1203 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[-1].StrVal); CHECK_FOR_ERROR ;} break; - case 40: -#line 1201 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 52: +#line 1207 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; CHECK_FOR_ERROR ;} break; - case 41: -#line 1206 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 53: +#line 1212 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} break; - case 42: -#line 1207 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 54: +#line 1213 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;} break; - case 43: -#line 1208 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 55: +#line 1214 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} break; - case 44: -#line 1209 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 56: +#line 1215 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::AppendingLinkage; ;} break; - case 45: -#line 1210 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 57: +#line 1216 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;} break; - case 46: -#line 1211 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 58: +#line 1217 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;} break; - case 47: -#line 1212 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 59: +#line 1218 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;} break; - case 48: -#line 1213 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 60: +#line 1219 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} break; - case 49: -#line 1215 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 61: +#line 1221 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::C; ;} break; - case 50: -#line 1216 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 62: +#line 1222 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::C; ;} break; - case 51: -#line 1217 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 63: +#line 1223 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::CSRet; ;} break; - case 52: -#line 1218 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 64: +#line 1224 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::Fast; ;} break; - case 53: -#line 1219 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 65: +#line 1225 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::Cold; ;} break; - case 54: -#line 1220 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 66: +#line 1226 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::X86_StdCall; ;} break; - case 55: -#line 1221 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 67: +#line 1227 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = CallingConv::X86_FastCall; ;} break; - case 56: -#line 1222 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 68: +#line 1228 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((unsigned)(yyvsp[0].UInt64Val) != (yyvsp[0].UInt64Val)) GEN_ERROR("Calling conv too large!"); @@ -3152,13 +3208,13 @@ yyreduce: ;} break; - case 57: -#line 1231 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 69: +#line 1237 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = 0; ;} break; - case 58: -#line 1232 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 70: +#line 1238 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = (yyvsp[0].UInt64Val); if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) @@ -3167,13 +3223,13 @@ yyreduce: ;} break; - case 59: -#line 1238 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 71: +#line 1244 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = 0; ;} break; - case 60: -#line 1239 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 72: +#line 1245 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.UIntVal) = (yyvsp[0].UInt64Val); if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) @@ -3182,8 +3238,8 @@ yyreduce: ;} break; - case 61: -#line 1247 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 73: +#line 1253 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { for (unsigned i = 0, e = strlen((yyvsp[0].StrVal)); i != e; ++i) if ((yyvsp[0].StrVal)[i] == '"' || (yyvsp[0].StrVal)[i] == '\\') @@ -3193,28 +3249,28 @@ yyreduce: ;} break; - case 62: -#line 1255 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 74: +#line 1261 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; ;} break; - case 63: -#line 1256 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 75: +#line 1262 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = (yyvsp[0].StrVal); ;} break; - case 64: -#line 1261 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 76: +#line 1267 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" {;} break; - case 65: -#line 1262 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 77: +#line 1268 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" {;} break; - case 66: -#line 1263 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 78: +#line 1269 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurGV->setSection((yyvsp[0].StrVal)); free((yyvsp[0].StrVal)); @@ -3222,8 +3278,8 @@ yyreduce: ;} break; - case 67: -#line 1268 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 79: +#line 1274 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[0].UInt64Val) != 0 && !isPowerOf2_32((yyvsp[0].UInt64Val))) GEN_ERROR("Alignment must be a power of two!"); @@ -3232,186 +3288,209 @@ yyreduce: ;} break; - case 69: -#line 1282 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" - { (yyval.TypeVal) = new PATypeHolder((yyvsp[0].PrimType)); ;} + case 81: +#line 1288 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" + { + (yyval.TypeVal).type = new PATypeHolder((yyvsp[0].TypeVal).type->get()); + (yyval.TypeVal).signedness = (yyvsp[0].TypeVal).signedness; +;} break; - case 71: -#line 1283 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" - { (yyval.TypeVal) = new PATypeHolder((yyvsp[0].PrimType)); ;} + case 83: +#line 1292 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" + { + (yyval.TypeVal).type = new PATypeHolder((yyvsp[0].TypeVal).type->get()); + (yyval.TypeVal).signedness = (yyvsp[0].TypeVal).signedness; +;} break; - case 72: -#line 1285 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 84: +#line 1297 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[0].TypeVal))->getDescription()); + GEN_ERROR("Invalid upreference in type: " + + ((yyvsp[0].TypeVal).type->get())->getDescription()); (yyval.TypeVal) = (yyvsp[0].TypeVal); CHECK_FOR_ERROR - ;} +;} break; - case 86: -#line 1297 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 98: +#line 1310 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.TypeVal) = new PATypeHolder(OpaqueType::get()); + (yyval.TypeVal).type = new PATypeHolder(OpaqueType::get()); + (yyval.TypeVal).signedness = isSignless; CHECK_FOR_ERROR ;} break; - case 87: -#line 1301 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 99: +#line 1315 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.TypeVal) = new PATypeHolder((yyvsp[0].PrimType)); + (yyval.TypeVal) = (yyvsp[0].TypeVal); CHECK_FOR_ERROR ;} break; - case 88: -#line 1305 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 100: +#line 1319 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Named types are also simple types... const Type* tmp = getTypeVal((yyvsp[0].ValIDVal)); CHECK_FOR_ERROR - (yyval.TypeVal) = new PATypeHolder(tmp); + (yyval.TypeVal).type = new PATypeHolder(tmp); + (yyval.TypeVal).signedness = isSignless; ;} break; - case 89: -#line 1313 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 101: +#line 1328 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Type UpReference if ((yyvsp[0].UInt64Val) > (uint64_t)~0U) GEN_ERROR("Value out of range!"); OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder UpRefs.push_back(UpRefRecord((unsigned)(yyvsp[0].UInt64Val), OT)); // Add to vector... - (yyval.TypeVal) = new PATypeHolder(OT); + (yyval.TypeVal).type = new PATypeHolder(OT); + (yyval.TypeVal).signedness = isSignless; UR_OUT("New Upreference!\n"); CHECK_FOR_ERROR ;} break; - case 90: -#line 1321 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 102: +#line 1337 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Function derived type? std::vector<const Type*> Params; - for (std::list<llvm::PATypeHolder>::iterator I = (yyvsp[-1].TypeList)->begin(), + for (std::list<TypeInfo>::iterator I = (yyvsp[-1].TypeList)->begin(), E = (yyvsp[-1].TypeList)->end(); I != E; ++I) - Params.push_back(*I); + Params.push_back(I->type->get()); bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(FunctionType::get(*(yyvsp[-3].TypeVal),Params,isVarArg))); + (yyval.TypeVal).type = new PATypeHolder(HandleUpRefs( + FunctionType::get((yyvsp[-3].TypeVal).type->get(),Params,isVarArg))); + (yyval.TypeVal).signedness = isSignless; delete (yyvsp[-1].TypeList); // Delete the argument list - delete (yyvsp[-3].TypeVal); // Delete the return type handle + delete (yyvsp[-3].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 91: -#line 1334 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 103: +#line 1352 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Sized array type? - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(ArrayType::get(*(yyvsp[-1].TypeVal), (unsigned)(yyvsp[-3].UInt64Val)))); - delete (yyvsp[-1].TypeVal); + (yyval.TypeVal).type = new PATypeHolder(HandleUpRefs( + ArrayType::get((yyvsp[-1].TypeVal).type->get(), (unsigned)(yyvsp[-3].UInt64Val)))); + (yyval.TypeVal).signedness = isSignless; + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 92: -#line 1339 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 104: +#line 1359 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Packed array type? - const llvm::Type* ElemTy = (yyvsp[-1].TypeVal)->get(); - if ((unsigned)(yyvsp[-3].UInt64Val) != (yyvsp[-3].UInt64Val)) - GEN_ERROR("Unsigned result not equal to signed result"); - if (!ElemTy->isPrimitiveType()) - GEN_ERROR("Elemental type of a PackedType must be primitive"); - if (!isPowerOf2_32((yyvsp[-3].UInt64Val))) - GEN_ERROR("Vector length should be a power of 2!"); - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(PackedType::get(*(yyvsp[-1].TypeVal), (unsigned)(yyvsp[-3].UInt64Val)))); - delete (yyvsp[-1].TypeVal); - CHECK_FOR_ERROR + const llvm::Type* ElemTy = (yyvsp[-1].TypeVal).type->get(); + if ((unsigned)(yyvsp[-3].UInt64Val) != (yyvsp[-3].UInt64Val)) + GEN_ERROR("Unsigned result not equal to signed result"); + if (!ElemTy->isPrimitiveType()) + GEN_ERROR("Elemental type of a PackedType must be primitive"); + if (!isPowerOf2_32((yyvsp[-3].UInt64Val))) + GEN_ERROR("Vector length should be a power of 2!"); + (yyval.TypeVal).type = new PATypeHolder(HandleUpRefs( + PackedType::get((yyvsp[-1].TypeVal).type->get(), (unsigned)(yyvsp[-3].UInt64Val)))); + (yyval.TypeVal).signedness = isSignless; + delete (yyvsp[-1].TypeVal).type; + CHECK_FOR_ERROR ;} break; - case 93: -#line 1351 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 105: +#line 1373 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Structure type? std::vector<const Type*> Elements; - for (std::list<llvm::PATypeHolder>::iterator I = (yyvsp[-1].TypeList)->begin(), + for (std::list<TypeInfo>::iterator I = (yyvsp[-1].TypeList)->begin(), E = (yyvsp[-1].TypeList)->end(); I != E; ++I) - Elements.push_back(*I); + Elements.push_back(I->type->get()); - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); + (yyval.TypeVal).type = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); + (yyval.TypeVal).signedness = isSignless; delete (yyvsp[-1].TypeList); CHECK_FOR_ERROR ;} break; - case 94: -#line 1361 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 106: +#line 1384 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Empty structure type? - (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector<const Type*>())); + (yyval.TypeVal).type = new PATypeHolder(StructType::get(std::vector<const Type*>())); + (yyval.TypeVal).signedness = isSignless; CHECK_FOR_ERROR ;} break; - case 95: -#line 1365 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 107: +#line 1389 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Pointer type? - if (*(yyvsp[-1].TypeVal) == Type::LabelTy) + if ((yyvsp[-1].TypeVal).type->get() == Type::LabelTy) GEN_ERROR("Cannot form a pointer to a basic block"); - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(PointerType::get(*(yyvsp[-1].TypeVal)))); - delete (yyvsp[-1].TypeVal); + (yyval.TypeVal).type = new PATypeHolder(HandleUpRefs(PointerType::get((yyvsp[-1].TypeVal).type->get()))); + (yyval.TypeVal).signedness = (yyvsp[-1].TypeVal).signedness; + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 96: -#line 1376 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 108: +#line 1401 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.TypeList) = new std::list<PATypeHolder>(); - (yyval.TypeList)->push_back(*(yyvsp[0].TypeVal)); delete (yyvsp[0].TypeVal); + (yyval.TypeList) = new std::list<TypeInfo>(); + (yyval.TypeList)->push_back((yyvsp[0].TypeVal)); CHECK_FOR_ERROR ;} break; - case 97: -#line 1381 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 109: +#line 1406 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - ((yyval.TypeList)=(yyvsp[-2].TypeList))->push_back(*(yyvsp[0].TypeVal)); delete (yyvsp[0].TypeVal); + ((yyval.TypeList)=(yyvsp[-2].TypeList))->push_back((yyvsp[0].TypeVal)); CHECK_FOR_ERROR ;} break; - case 99: -#line 1388 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 111: +#line 1413 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - ((yyval.TypeList)=(yyvsp[-2].TypeList))->push_back(Type::VoidTy); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); TI.signedness = isSignless; + ((yyval.TypeList)=(yyvsp[-2].TypeList))->push_back(TI); CHECK_FOR_ERROR ;} break; - case 100: -#line 1392 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 112: +#line 1419 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - ((yyval.TypeList) = new std::list<PATypeHolder>())->push_back(Type::VoidTy); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); TI.signedness = isSignless; + ((yyval.TypeList) = new std::list<TypeInfo>())->push_back(TI); CHECK_FOR_ERROR ;} break; - case 101: -#line 1396 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 113: +#line 1425 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.TypeList) = new std::list<PATypeHolder>(); + (yyval.TypeList) = new std::list<TypeInfo>(); CHECK_FOR_ERROR ;} break; - case 102: -#line 1407 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 114: +#line 1436 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr - const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-3].TypeVal)->get()); + const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-3].TypeVal).type->get()); if (ATy == 0) GEN_ERROR("Cannot make array constant with type: '" + - (*(yyvsp[-3].TypeVal))->getDescription() + "'!"); + ((yyvsp[-3].TypeVal).type->get())->getDescription() + "'!"); const Type *ETy = ATy->getElementType(); int NumElements = ATy->getNumElements(); @@ -3430,36 +3509,36 @@ yyreduce: } (yyval.ConstVal) = ConstantArray::get(ATy, *(yyvsp[-1].ConstVector)); - delete (yyvsp[-3].TypeVal); delete (yyvsp[-1].ConstVector); + delete (yyvsp[-3].TypeVal).type; delete (yyvsp[-1].ConstVector); CHECK_FOR_ERROR ;} break; - case 103: -#line 1433 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 115: +#line 1462 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-2].TypeVal)->get()); + const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-2].TypeVal).type->get()); if (ATy == 0) GEN_ERROR("Cannot make array constant with type: '" + - (*(yyvsp[-2].TypeVal))->getDescription() + "'!"); + ((yyvsp[-2].TypeVal).type->get())->getDescription() + "'!"); int NumElements = ATy->getNumElements(); if (NumElements != -1 && NumElements != 0) GEN_ERROR("Type mismatch: constant sized array initialized with 0" " arguments, but has size of " + itostr(NumElements) +"!"); (yyval.ConstVal) = ConstantArray::get(ATy, std::vector<Constant*>()); - delete (yyvsp[-2].TypeVal); + delete (yyvsp[-2].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 104: -#line 1447 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 116: +#line 1476 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-2].TypeVal)->get()); + const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-2].TypeVal).type->get()); if (ATy == 0) GEN_ERROR("Cannot make array constant with type: '" + - (*(yyvsp[-2].TypeVal))->getDescription() + "'!"); + ((yyvsp[-2].TypeVal).type->get())->getDescription() + "'!"); int NumElements = ATy->getNumElements(); const Type *ETy = ATy->getElementType(); @@ -3482,18 +3561,18 @@ yyreduce: } free((yyvsp[0].StrVal)); (yyval.ConstVal) = ConstantArray::get(ATy, Vals); - delete (yyvsp[-2].TypeVal); + delete (yyvsp[-2].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 105: -#line 1477 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 117: +#line 1506 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized arr - const PackedType *PTy = dyn_cast<PackedType>((yyvsp[-3].TypeVal)->get()); + const PackedType *PTy = dyn_cast<PackedType>((yyvsp[-3].TypeVal).type->get()); if (PTy == 0) GEN_ERROR("Cannot make packed constant with type: '" + - (*(yyvsp[-3].TypeVal))->getDescription() + "'!"); + (yyvsp[-3].TypeVal).type->get()->getDescription() + "'!"); const Type *ETy = PTy->getElementType(); int NumElements = PTy->getNumElements(); @@ -3512,18 +3591,18 @@ yyreduce: } (yyval.ConstVal) = ConstantPacked::get(PTy, *(yyvsp[-1].ConstVector)); - delete (yyvsp[-3].TypeVal); delete (yyvsp[-1].ConstVector); + delete (yyvsp[-3].TypeVal).type; delete (yyvsp[-1].ConstVector); CHECK_FOR_ERROR ;} break; - case 106: -#line 1503 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 118: +#line 1532 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const StructType *STy = dyn_cast<StructType>((yyvsp[-3].TypeVal)->get()); + const StructType *STy = dyn_cast<StructType>((yyvsp[-3].TypeVal).type->get()); if (STy == 0) GEN_ERROR("Cannot make struct constant with type: '" + - (*(yyvsp[-3].TypeVal))->getDescription() + "'!"); + (yyvsp[-3].TypeVal).type->get()->getDescription() + "'!"); if ((yyvsp[-1].ConstVector)->size() != STy->getNumContainedTypes()) GEN_ERROR("Illegal number of initializers for structure type!"); @@ -3537,55 +3616,55 @@ yyreduce: " of structure initializer!"); (yyval.ConstVal) = ConstantStruct::get(STy, *(yyvsp[-1].ConstVector)); - delete (yyvsp[-3].TypeVal); delete (yyvsp[-1].ConstVector); + delete (yyvsp[-3].TypeVal).type; delete (yyvsp[-1].ConstVector); CHECK_FOR_ERROR ;} break; - case 107: -#line 1524 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 119: +#line 1553 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const StructType *STy = dyn_cast<StructType>((yyvsp[-2].TypeVal)->get()); + const StructType *STy = dyn_cast<StructType>((yyvsp[-2].TypeVal).type->get()); if (STy == 0) GEN_ERROR("Cannot make struct constant with type: '" + - (*(yyvsp[-2].TypeVal))->getDescription() + "'!"); + (yyvsp[-2].TypeVal).type->get()->getDescription() + "'!"); if (STy->getNumContainedTypes() != 0) GEN_ERROR("Illegal number of initializers for structure type!"); (yyval.ConstVal) = ConstantStruct::get(STy, std::vector<Constant*>()); - delete (yyvsp[-2].TypeVal); + delete (yyvsp[-2].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 108: -#line 1537 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 120: +#line 1566 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const PointerType *PTy = dyn_cast<PointerType>((yyvsp[-1].TypeVal)->get()); + const PointerType *PTy = dyn_cast<PointerType>((yyvsp[-1].TypeVal).type->get()); if (PTy == 0) GEN_ERROR("Cannot make null pointer constant with type: '" + - (*(yyvsp[-1].TypeVal))->getDescription() + "'!"); + (yyvsp[-1].TypeVal).type->get()->getDescription() + "'!"); (yyval.ConstVal) = ConstantPointerNull::get(PTy); - delete (yyvsp[-1].TypeVal); + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 109: -#line 1547 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 121: +#line 1576 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.ConstVal) = UndefValue::get((yyvsp[-1].TypeVal)->get()); - delete (yyvsp[-1].TypeVal); + (yyval.ConstVal) = UndefValue::get((yyvsp[-1].TypeVal).type->get()); + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 110: -#line 1552 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 122: +#line 1581 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const PointerType *Ty = dyn_cast<PointerType>((yyvsp[-1].TypeVal)->get()); + const PointerType *Ty = dyn_cast<PointerType>((yyvsp[-1].TypeVal).type->get()); if (Ty == 0) GEN_ERROR("Global const reference must be a pointer type!"); @@ -3642,97 +3721,112 @@ yyreduce: } (yyval.ConstVal) = cast<GlobalValue>(V); - delete (yyvsp[-1].TypeVal); // Free the type handle + delete (yyvsp[-1].TypeVal).type; // Free the type handle CHECK_FOR_ERROR ;} break; - case 111: -#line 1613 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 123: +#line 1642 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if ((yyvsp[-1].TypeVal)->get() != (yyvsp[0].ConstVal)->getType()) + if ((yyvsp[-1].TypeVal).type->get() != (yyvsp[0].ConstVal)->getType()) GEN_ERROR("Mismatched types for constant expression!"); (yyval.ConstVal) = (yyvsp[0].ConstVal); - delete (yyvsp[-1].TypeVal); + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 112: -#line 1620 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 124: +#line 1649 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const Type *Ty = (yyvsp[-1].TypeVal)->get(); + const Type *Ty = (yyvsp[-1].TypeVal).type->get(); if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || isa<OpaqueType>(Ty)) GEN_ERROR("Cannot create a null initialized value of this type!"); (yyval.ConstVal) = Constant::getNullValue(Ty); - delete (yyvsp[-1].TypeVal); + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 113: -#line 1629 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 125: +#line 1658 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // integral constants - if (!ConstantInt::isValueValidForType((yyvsp[-1].PrimType), (yyvsp[0].SInt64Val))) + if (!ConstantInt::isValueValidForType((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].SInt64Val))) GEN_ERROR("Constant value doesn't fit in type!"); - (yyval.ConstVal) = ConstantInt::get((yyvsp[-1].PrimType), (yyvsp[0].SInt64Val)); + (yyval.ConstVal) = ConstantInt::get((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].SInt64Val)); CHECK_FOR_ERROR ;} break; - case 114: -#line 1635 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 126: +#line 1664 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // integral constants - if (!ConstantInt::isValueValidForType((yyvsp[-1].PrimType), (yyvsp[0].UInt64Val))) + if (!ConstantInt::isValueValidForType((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].UInt64Val))) GEN_ERROR("Constant value doesn't fit in type!"); - (yyval.ConstVal) = ConstantInt::get((yyvsp[-1].PrimType), (yyvsp[0].UInt64Val)); + (yyval.ConstVal) = ConstantInt::get((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].UInt64Val)); CHECK_FOR_ERROR ;} break; - case 115: -#line 1641 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 127: +#line 1670 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Boolean constants (yyval.ConstVal) = ConstantBool::getTrue(); CHECK_FOR_ERROR ;} break; - case 116: -#line 1645 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 128: +#line 1674 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Boolean constants (yyval.ConstVal) = ConstantBool::getFalse(); CHECK_FOR_ERROR ;} break; - case 117: -#line 1649 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 129: +#line 1678 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Float & Double constants - if (!ConstantFP::isValueValidForType((yyvsp[-1].PrimType), (yyvsp[0].FPVal))) + if (!ConstantFP::isValueValidForType((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].FPVal))) GEN_ERROR("Floating point constant invalid for type!!"); - (yyval.ConstVal) = ConstantFP::get((yyvsp[-1].PrimType), (yyvsp[0].FPVal)); + (yyval.ConstVal) = ConstantFP::get((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].FPVal)); CHECK_FOR_ERROR ;} break; - case 118: -#line 1657 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 130: +#line 1686 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if (!(yyvsp[-3].ConstVal)->getType()->isFirstClassType()) + Constant *Val = (yyvsp[-3].ConstVal); + const Type *Ty = (yyvsp[-1].TypeVal).type->get(); + if (!Val->getType()->isFirstClassType()) GEN_ERROR("cast constant expression from a non-primitive type: '" + - (yyvsp[-3].ConstVal)->getType()->getDescription() + "'!"); - if (!(yyvsp[-1].TypeVal)->get()->isFirstClassType()) + Val->getType()->getDescription() + "'!"); + if (!Ty->isFirstClassType()) GEN_ERROR("cast constant expression to a non-primitive type: '" + - (yyvsp[-1].TypeVal)->get()->getDescription() + "'!"); - (yyval.ConstVal) = ConstantExpr::getCast((yyvsp[-3].ConstVal), (yyvsp[-1].TypeVal)->get()); - delete (yyvsp[-1].TypeVal); - CHECK_FOR_ERROR + Ty->getDescription() + "'!"); + if ((yyvsp[-5].CastOpVal).obsolete) { + if (Ty == Type::BoolTy) { + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + (yyval.ConstVal) = ConstantExpr::get(Instruction::SetNE, Val, + Constant::getNullValue(Val->getType())); + } else if (Val->getType()->isFloatingPoint() && isa<PointerType>(Ty)) { + Constant *CE = ConstantExpr::getFPToUI(Val, Type::ULongTy); + (yyval.ConstVal) = ConstantExpr::getIntToPtr(CE, Ty); + } else { + (yyval.ConstVal) = ConstantExpr::getCast(Val, Ty); + } + } else { + (yyval.ConstVal) = ConstantExpr::getCast((yyvsp[-5].CastOpVal).opcode, (yyvsp[-3].ConstVal), (yyvsp[-1].TypeVal).type->get()); + } + delete (yyvsp[-1].TypeVal).type; ;} break; - case 119: -#line 1668 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 131: +#line 1712 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!isa<PointerType>((yyvsp[-2].ConstVal)->getType())) GEN_ERROR("GetElementPtr requires a pointer operand!"); @@ -3767,8 +3861,8 @@ yyreduce: ;} break; - case 120: -#line 1700 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 132: +#line 1744 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[-5].ConstVal)->getType() != Type::BoolTy) GEN_ERROR("Select condition must be of boolean type!"); @@ -3779,14 +3873,14 @@ yyreduce: ;} break; - case 121: -#line 1708 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 133: +#line 1752 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[-3].ConstVal)->getType() != (yyvsp[-1].ConstVal)->getType()) GEN_ERROR("Binary operator types must match!"); // First, make sure we're dealing with the right opcode by upgrading from // obsolete versions. - sanitizeOpCode((yyvsp[-5].BinaryOpVal),(yyvsp[-3].ConstVal)->getType()); + sanitizeOpcode((yyvsp[-5].BinaryOpVal), (yyvsp[-3].ConstVal)->getType()); CHECK_FOR_ERROR; // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs. @@ -3810,8 +3904,8 @@ yyreduce: ;} break; - case 122: -#line 1735 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 134: +#line 1779 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[-3].ConstVal)->getType() != (yyvsp[-1].ConstVal)->getType()) GEN_ERROR("Logical operator types must match!"); @@ -3825,8 +3919,8 @@ yyreduce: ;} break; - case 123: -#line 1746 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 135: +#line 1790 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[-3].ConstVal)->getType() != (yyvsp[-1].ConstVal)->getType()) GEN_ERROR("setcc operand types must match!"); @@ -3835,23 +3929,23 @@ yyreduce: ;} break; - case 124: -#line 1752 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 136: +#line 1796 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[-1].ConstVal)->getType() != Type::UByteTy) GEN_ERROR("Shift count for shift constant must be unsigned byte!"); if (!(yyvsp[-3].ConstVal)->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); // Handle opcode upgrade situations - sanitizeOpCode((yyvsp[-5].OtherOpVal), (yyvsp[-3].ConstVal)->getType()); + sanitizeOpcode((yyvsp[-5].OtherOpVal), (yyvsp[-3].ConstVal)->getType()); CHECK_FOR_ERROR; (yyval.ConstVal) = ConstantExpr::get((yyvsp[-5].OtherOpVal).opcode, (yyvsp[-3].ConstVal), (yyvsp[-1].ConstVal)); CHECK_FOR_ERROR ;} break; - case 125: -#line 1763 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 137: +#line 1807 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!ExtractElementInst::isValidOperands((yyvsp[-3].ConstVal), (yyvsp[-1].ConstVal))) GEN_ERROR("Invalid extractelement operands!"); @@ -3860,8 +3954,8 @@ yyreduce: ;} break; - case 126: -#line 1769 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 138: +#line 1813 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!InsertElementInst::isValidOperands((yyvsp[-5].ConstVal), (yyvsp[-3].ConstVal), (yyvsp[-1].ConstVal))) GEN_ERROR("Invalid insertelement operands!"); @@ -3870,8 +3964,8 @@ yyreduce: ;} break; - case 127: -#line 1775 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 139: +#line 1819 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!ShuffleVectorInst::isValidOperands((yyvsp[-5].ConstVal), (yyvsp[-3].ConstVal), (yyvsp[-1].ConstVal))) GEN_ERROR("Invalid shufflevector operands!"); @@ -3880,16 +3974,16 @@ yyreduce: ;} break; - case 128: -#line 1784 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 140: +#line 1828 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { ((yyval.ConstVector) = (yyvsp[-2].ConstVector))->push_back((yyvsp[0].ConstVal)); CHECK_FOR_ERROR ;} break; - case 129: -#line 1788 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 141: +#line 1832 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ConstVector) = new std::vector<Constant*>(); (yyval.ConstVector)->push_back((yyvsp[0].ConstVal)); @@ -3897,18 +3991,18 @@ yyreduce: ;} break; - case 130: -#line 1796 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 142: +#line 1840 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; ;} break; - case 131: -#line 1796 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 143: +#line 1840 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; ;} break; - case 132: -#line 1806 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 144: +#line 1850 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = ParserResult = (yyvsp[0].ModuleVal); CurModule.ModuleDone(); @@ -3916,8 +4010,8 @@ yyreduce: ;} break; - case 133: -#line 1814 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 145: +#line 1858 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = (yyvsp[-1].ModuleVal); CurFun.FunctionDone(); @@ -3925,32 +4019,32 @@ yyreduce: ;} break; - case 134: -#line 1819 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 146: +#line 1863 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = (yyvsp[-1].ModuleVal); CHECK_FOR_ERROR ;} break; - case 135: -#line 1823 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 147: +#line 1867 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = (yyvsp[-3].ModuleVal); CHECK_FOR_ERROR ;} break; - case 136: -#line 1827 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 148: +#line 1871 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = (yyvsp[-1].ModuleVal); CHECK_FOR_ERROR ;} break; - case 137: -#line 1831 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 149: +#line 1875 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ModuleVal) = CurModule.CurrentModule; // Emit an error if there are any unresolved types left. @@ -3966,8 +4060,8 @@ yyreduce: ;} break; - case 138: -#line 1846 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 150: +#line 1890 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Eagerly resolve types. This is not an optimization, this is a // requirement that is due to the fact that we could have this: @@ -3978,36 +4072,36 @@ yyreduce: // If types are not resolved eagerly, then the two types will not be // determined to be the same type! // - ResolveTypeTo((yyvsp[-2].StrVal), *(yyvsp[0].TypeVal)); + ResolveTypeTo((yyvsp[-2].StrVal), (yyvsp[0].TypeVal).type->get()); - if (!setTypeName(*(yyvsp[0].TypeVal), (yyvsp[-2].StrVal)) && !(yyvsp[-2].StrVal)) { + if (!setTypeName((yyvsp[0].TypeVal).type->get(), (yyvsp[-2].StrVal)) && !(yyvsp[-2].StrVal)) { CHECK_FOR_ERROR // If this is a named type that is not a redefinition, add it to the slot // table. - CurModule.Types.push_back(*(yyvsp[0].TypeVal)); + CurModule.Types.push_back((yyvsp[0].TypeVal)); + } else { + delete (yyvsp[0].TypeVal).type; } - - delete (yyvsp[0].TypeVal); CHECK_FOR_ERROR ;} break; - case 139: -#line 1868 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 151: +#line 1912 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Function prototypes can be in const pool CHECK_FOR_ERROR ;} break; - case 140: -#line 1871 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 152: +#line 1915 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Asm blocks can be in the const pool CHECK_FOR_ERROR ;} break; - case 141: -#line 1874 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 153: +#line 1918 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[0].ConstVal) == 0) GEN_ERROR("Global value initializer is not a constant!"); @@ -4016,87 +4110,90 @@ yyreduce: ;} break; - case 142: -#line 1879 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 154: +#line 1923 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; ;} break; - case 143: -#line 1882 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 155: +#line 1926 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - CurGV = ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::ExternalLinkage, (yyvsp[-1].BoolVal), *(yyvsp[0].TypeVal), 0); + CurGV = ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::ExternalLinkage, (yyvsp[-1].BoolVal), + (yyvsp[0].TypeVal).type->get(), 0); CHECK_FOR_ERROR - delete (yyvsp[0].TypeVal); + delete (yyvsp[0].TypeVal).type; ;} break; - case 144: -#line 1886 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 156: +#line 1931 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; CHECK_FOR_ERROR ;} break; - case 145: -#line 1890 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 157: +#line 1935 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - CurGV = ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::DLLImportLinkage, (yyvsp[-1].BoolVal), *(yyvsp[0].TypeVal), 0); + CurGV = ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::DLLImportLinkage, (yyvsp[-1].BoolVal), + (yyvsp[0].TypeVal).type->get(), 0); CHECK_FOR_ERROR - delete (yyvsp[0].TypeVal); + delete (yyvsp[0].TypeVal).type; ;} break; - case 146: -#line 1894 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 158: +#line 1940 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; CHECK_FOR_ERROR ;} break; - case 147: -#line 1898 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 159: +#line 1944 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurGV = - ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::ExternalWeakLinkage, (yyvsp[-1].BoolVal), *(yyvsp[0].TypeVal), 0); + ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::ExternalWeakLinkage, (yyvsp[-1].BoolVal), + (yyvsp[0].TypeVal).type->get(), 0); CHECK_FOR_ERROR - delete (yyvsp[0].TypeVal); + delete (yyvsp[0].TypeVal).type; ;} break; - case 148: -#line 1903 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 160: +#line 1950 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurGV = 0; CHECK_FOR_ERROR ;} break; - case 149: -#line 1907 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 161: +#line 1954 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; - case 150: -#line 1910 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 162: +#line 1957 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; - case 151: -#line 1913 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 163: +#line 1960 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { ;} break; - case 152: -#line 1917 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 164: +#line 1964 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); char *EndStr = UnEscapeLexed((yyvsp[0].StrVal), true); @@ -4111,26 +4208,26 @@ yyreduce: ;} break; - case 153: -#line 1930 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 165: +#line 1977 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Endianness) = Module::BigEndian; ;} break; - case 154: -#line 1931 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 166: +#line 1978 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.Endianness) = Module::LittleEndian; ;} break; - case 155: -#line 1933 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 167: +#line 1980 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setEndianness((yyvsp[0].Endianness)); CHECK_FOR_ERROR ;} break; - case 156: -#line 1937 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 168: +#line 1984 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[0].UInt64Val) == 32) CurModule.CurrentModule->setPointerSize(Module::Pointer32); @@ -4142,24 +4239,24 @@ yyreduce: ;} break; - case 157: -#line 1946 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 169: +#line 1993 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setTargetTriple((yyvsp[0].StrVal)); free((yyvsp[0].StrVal)); ;} break; - case 158: -#line 1950 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 170: +#line 1997 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->setDataLayout((yyvsp[0].StrVal)); free((yyvsp[0].StrVal)); ;} break; - case 160: -#line 1957 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 172: +#line 2004 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary((yyvsp[0].StrVal)); free((yyvsp[0].StrVal)); @@ -4167,8 +4264,8 @@ yyreduce: ;} break; - case 161: -#line 1962 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 173: +#line 2009 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurModule.CurrentModule->addLibrary((yyvsp[0].StrVal)); free((yyvsp[0].StrVal)); @@ -4176,30 +4273,30 @@ yyreduce: ;} break; - case 162: -#line 1967 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 174: +#line 2014 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CHECK_FOR_ERROR ;} break; - case 166: -#line 1977 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 178: +#line 2024 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.StrVal) = 0; ;} break; - case 167: -#line 1979 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 179: +#line 2026 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if (*(yyvsp[-1].TypeVal) == Type::VoidTy) + if ((yyvsp[-1].TypeVal).type->get() == Type::VoidTy) GEN_ERROR("void typed arguments are invalid!"); - (yyval.ArgVal) = new std::pair<PATypeHolder*, char*>((yyvsp[-1].TypeVal), (yyvsp[0].StrVal)); + (yyval.ArgVal) = new std::pair<TypeInfo, char*>((yyvsp[-1].TypeVal), (yyvsp[0].StrVal)); CHECK_FOR_ERROR ;} break; - case 168: -#line 1986 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 180: +#line 2033 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = (yyvsp[-2].ArgList); (yyvsp[-2].ArgList)->push_back(*(yyvsp[0].ArgVal)); @@ -4208,74 +4305,80 @@ yyreduce: ;} break; - case 169: -#line 1992 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 181: +#line 2039 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.ArgList) = new std::vector<std::pair<PATypeHolder*,char*> >(); + (yyval.ArgList) = new std::vector<std::pair<TypeInfo,char*> >(); (yyval.ArgList)->push_back(*(yyvsp[0].ArgVal)); delete (yyvsp[0].ArgVal); CHECK_FOR_ERROR ;} break; - case 170: -#line 1999 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 182: +#line 2046 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = (yyvsp[0].ArgList); CHECK_FOR_ERROR ;} break; - case 171: -#line 2003 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 183: +#line 2050 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = (yyvsp[-2].ArgList); - (yyval.ArgList)->push_back(std::pair<PATypeHolder*, - char*>(new PATypeHolder(Type::VoidTy), 0)); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); + TI.signedness = isSignless; + (yyval.ArgList)->push_back(std::pair<TypeInfo,char*>(TI,(char*)0)); CHECK_FOR_ERROR ;} break; - case 172: -#line 2009 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 184: +#line 2058 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.ArgList) = new std::vector<std::pair<PATypeHolder*,char*> >(); - (yyval.ArgList)->push_back(std::make_pair(new PATypeHolder(Type::VoidTy), (char*)0)); + (yyval.ArgList) = new std::vector<std::pair<TypeInfo,char*> >(); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); + TI.signedness = isSignless; + (yyval.ArgList)->push_back(std::make_pair(TI, (char*)0)); CHECK_FOR_ERROR ;} break; - case 173: -#line 2014 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 185: +#line 2066 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ArgList) = 0; CHECK_FOR_ERROR ;} break; - case 174: -#line 2020 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 186: +#line 2072 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { UnEscapeLexed((yyvsp[-5].StrVal)); std::string FunctionName((yyvsp[-5].StrVal)); free((yyvsp[-5].StrVal)); // Free strdup'd memory! - if (!(*(yyvsp[-6].TypeVal))->isFirstClassType() && *(yyvsp[-6].TypeVal) != Type::VoidTy) + if (!((yyvsp[-6].TypeVal).type->get())->isFirstClassType() && (yyvsp[-6].TypeVal).type->get() != Type::VoidTy) GEN_ERROR("LLVM functions cannot return aggregate types!"); std::vector<const Type*> ParamTypeList; if ((yyvsp[-3].ArgList)) { // If there are arguments... - for (std::vector<std::pair<PATypeHolder*,char*> >::iterator I = (yyvsp[-3].ArgList)->begin(); + for (std::vector<std::pair<TypeInfo,char*> >::iterator I = (yyvsp[-3].ArgList)->begin(); I != (yyvsp[-3].ArgList)->end(); ++I) - ParamTypeList.push_back(I->first->get()); + ParamTypeList.push_back(I->first.type->get()); } bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; if (isVarArg) ParamTypeList.pop_back(); - const FunctionType *FT = FunctionType::get(*(yyvsp[-6].TypeVal), ParamTypeList, isVarArg); + const FunctionType *FT = FunctionType::get((yyvsp[-6].TypeVal).type->get(), ParamTypeList, + isVarArg); const PointerType *PFT = PointerType::get(FT); - delete (yyvsp[-6].TypeVal); + delete (yyvsp[-6].TypeVal).type; ValID ID; if (!FunctionName.empty()) { @@ -4329,29 +4432,27 @@ yyreduce: // Add all of the arguments we parsed to the function... if ((yyvsp[-3].ArgList)) { // Is null if empty... if (isVarArg) { // Nuke the last entry - assert((yyvsp[-3].ArgList)->back().first->get() == Type::VoidTy && (yyvsp[-3].ArgList)->back().second == 0&& - "Not a varargs marker!"); - delete (yyvsp[-3].ArgList)->back().first; + assert((yyvsp[-3].ArgList)->back().first.type->get() == Type::VoidTy && + (yyvsp[-3].ArgList)->back().second == 0 && "Not a varargs marker!"); + delete (yyvsp[-3].ArgList)->back().first.type; (yyvsp[-3].ArgList)->pop_back(); // Delete the last entry } Function::arg_iterator ArgIt = Fn->arg_begin(); - for (std::vector<std::pair<PATypeHolder*,char*> >::iterator I = (yyvsp[-3].ArgList)->begin(); + for (std::vector<std::pair<TypeInfo,char*> >::iterator I = (yyvsp[-3].ArgList)->begin(); I != (yyvsp[-3].ArgList)->end(); ++I, ++ArgIt) { - delete I->first; // Delete the typeholder... - + delete I->first.type; // Delete the typeholder... setValueName(ArgIt, I->second); // Insert arg into symtab... CHECK_FOR_ERROR InsertValue(ArgIt); } - delete (yyvsp[-3].ArgList); // We're now done with the argument list } CHECK_FOR_ERROR ;} break; - case 177: -#line 2116 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 189: +#line 2167 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = CurFun.CurrentFunction; @@ -4361,31 +4462,31 @@ yyreduce: ;} break; - case 180: -#line 2126 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 192: +#line 2177 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = (yyvsp[-1].FunctionVal); CHECK_FOR_ERROR ;} break; - case 182: -#line 2132 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 194: +#line 2183 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurFun.Linkage = GlobalValue::DLLImportLinkage; ;} break; - case 183: -#line 2133 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 195: +#line 2184 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurFun.Linkage = GlobalValue::DLLImportLinkage; ;} break; - case 184: -#line 2135 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 196: +#line 2186 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { CurFun.isDeclare = true; ;} break; - case 185: -#line 2135 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 197: +#line 2186 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = CurFun.CurrentFunction; CurFun.FunctionDone(); @@ -4393,100 +4494,95 @@ yyreduce: ;} break; - case 186: -#line 2145 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 198: +#line 2196 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR ;} break; - case 187: -#line 2149 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 199: +#line 2200 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR ;} break; - case 188: -#line 2154 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 200: +#line 2205 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // A reference to a direct constant (yyval.ValIDVal) = ValID::create((yyvsp[0].SInt64Val)); CHECK_FOR_ERROR ;} break; - case 189: -#line 2158 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 201: +#line 2209 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create((yyvsp[0].UInt64Val)); CHECK_FOR_ERROR ;} break; - case 190: -#line 2162 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 202: +#line 2213 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Perhaps it's an FP constant? (yyval.ValIDVal) = ValID::create((yyvsp[0].FPVal)); CHECK_FOR_ERROR ;} break; - case 191: -#line 2166 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 203: +#line 2217 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create(ConstantBool::getTrue()); CHECK_FOR_ERROR ;} break; - case 192: -#line 2170 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 204: +#line 2221 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create(ConstantBool::getFalse()); CHECK_FOR_ERROR ;} break; - case 193: -#line 2174 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 205: +#line 2225 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createNull(); CHECK_FOR_ERROR ;} break; - case 194: -#line 2178 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 206: +#line 2229 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::createUndef(); CHECK_FOR_ERROR ;} break; - case 195: -#line 2182 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 207: +#line 2233 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // A vector zero constant. (yyval.ValIDVal) = ValID::createZeroInit(); CHECK_FOR_ERROR ;} break; - case 196: -#line 2186 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 208: +#line 2237 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Nonempty unsized packed vector const Type *ETy = (*(yyvsp[-1].ConstVector))[0]->getType(); int NumElements = (yyvsp[-1].ConstVector)->size(); PackedType* pt = PackedType::get(ETy, NumElements); PATypeHolder* PTy = new PATypeHolder( - HandleUpRefs( - PackedType::get( - ETy, - NumElements) - ) - ); + HandleUpRefs(PackedType::get( ETy, NumElements))); // Verify all elements are correct type! for (unsigned i = 0; i < (yyvsp[-1].ConstVector)->size(); i++) { @@ -4502,16 +4598,16 @@ yyreduce: ;} break; - case 197: -#line 2211 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 209: +#line 2257 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValIDVal) = ValID::create((yyvsp[0].ConstVal)); CHECK_FOR_ERROR ;} break; - case 198: -#line 2215 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 210: +#line 2261 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { char *End = UnEscapeLexed((yyvsp[-2].StrVal), true); std::string AsmStr = std::string((yyvsp[-2].StrVal), End); @@ -4524,48 +4620,48 @@ yyreduce: ;} break; - case 199: -#line 2229 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 211: +#line 2275 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Is it an integer reference...? (yyval.ValIDVal) = ValID::create((yyvsp[0].SIntVal)); CHECK_FOR_ERROR ;} break; - case 200: -#line 2233 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 212: +#line 2279 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Is it a named reference...? (yyval.ValIDVal) = ValID::create((yyvsp[0].StrVal)); CHECK_FOR_ERROR ;} break; - case 203: -#line 2245 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 215: +#line 2291 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.ValueVal) = getVal(*(yyvsp[-1].TypeVal), (yyvsp[0].ValIDVal)); delete (yyvsp[-1].TypeVal); + (yyval.ValueVal) = getVal((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].ValIDVal)); delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 204: -#line 2250 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 216: +#line 2296 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.FunctionVal) = (yyvsp[-1].FunctionVal); CHECK_FOR_ERROR ;} break; - case 205: -#line 2254 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 217: +#line 2300 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Do not allow functions with 0 basic blocks (yyval.FunctionVal) = (yyvsp[-1].FunctionVal); CHECK_FOR_ERROR ;} break; - case 206: -#line 2263 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 218: +#line 2309 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { setValueName((yyvsp[0].TermInstVal), (yyvsp[-1].StrVal)); CHECK_FOR_ERROR @@ -4578,17 +4674,21 @@ yyreduce: ;} break; - case 207: -#line 2274 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 219: +#line 2320 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { + if (CastInst *CI1 = dyn_cast<CastInst>((yyvsp[0].InstVal))) + if (CastInst *CI2 = dyn_cast<CastInst>(CI1->getOperand(0))) + if (CI2->getParent() == 0) + (yyvsp[-1].BasicBlockVal)->getInstList().push_back(CI2); (yyvsp[-1].BasicBlockVal)->getInstList().push_back((yyvsp[0].InstVal)); (yyval.BasicBlockVal) = (yyvsp[-1].BasicBlockVal); CHECK_FOR_ERROR ;} break; - case 208: -#line 2279 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 220: +#line 2329 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BasicBlockVal) = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); CHECK_FOR_ERROR @@ -4603,8 +4703,8 @@ yyreduce: ;} break; - case 209: -#line 2291 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 221: +#line 2341 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BasicBlockVal) = CurBB = getBBVal(ValID::create((yyvsp[0].StrVal)), true); CHECK_FOR_ERROR @@ -4619,24 +4719,24 @@ yyreduce: ;} break; - case 210: -#line 2304 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 222: +#line 2354 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Return with a result... (yyval.TermInstVal) = new ReturnInst((yyvsp[0].ValueVal)); CHECK_FOR_ERROR ;} break; - case 211: -#line 2308 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 223: +#line 2358 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Return with no result... (yyval.TermInstVal) = new ReturnInst(); CHECK_FOR_ERROR ;} break; - case 212: -#line 2312 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 224: +#line 2362 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Unconditional Branch... BasicBlock* tmpBB = getBBVal((yyvsp[0].ValIDVal)); CHECK_FOR_ERROR @@ -4644,8 +4744,8 @@ yyreduce: ;} break; - case 213: -#line 2317 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 225: +#line 2367 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { BasicBlock* tmpBBA = getBBVal((yyvsp[-3].ValIDVal)); CHECK_FOR_ERROR @@ -4657,10 +4757,10 @@ yyreduce: ;} break; - case 214: -#line 2326 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 226: +#line 2376 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - Value* tmpVal = getVal((yyvsp[-7].PrimType), (yyvsp[-6].ValIDVal)); + Value* tmpVal = getVal((yyvsp[-7].TypeVal).type->get(), (yyvsp[-6].ValIDVal)); CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal((yyvsp[-3].ValIDVal)); CHECK_FOR_ERROR @@ -4680,10 +4780,10 @@ yyreduce: ;} break; - case 215: -#line 2345 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 227: +#line 2395 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - Value* tmpVal = getVal((yyvsp[-6].PrimType), (yyvsp[-5].ValIDVal)); + Value* tmpVal = getVal((yyvsp[-6].TypeVal).type->get(), (yyvsp[-5].ValIDVal)); CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal((yyvsp[-2].ValIDVal)); CHECK_FOR_ERROR @@ -4693,13 +4793,13 @@ yyreduce: ;} break; - case 216: -#line 2355 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 228: +#line 2405 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { const PointerType *PFTy; const FunctionType *Ty; - if (!(PFTy = dyn_cast<PointerType>((yyvsp[-10].TypeVal)->get())) || + if (!(PFTy = dyn_cast<PointerType>((yyvsp[-10].TypeVal).type->get())) || !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector<const Type*> ParamTypes; @@ -4712,7 +4812,7 @@ yyreduce: bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); - Ty = FunctionType::get((yyvsp[-10].TypeVal)->get(), ParamTypes, isVarArg); + Ty = FunctionType::get((yyvsp[-10].TypeVal).type->get(), ParamTypes, isVarArg); PFTy = PointerType::get(Ty); } @@ -4746,33 +4846,33 @@ yyreduce: } cast<InvokeInst>((yyval.TermInstVal))->setCallingConv((yyvsp[-11].UIntVal)); - delete (yyvsp[-10].TypeVal); + delete (yyvsp[-10].TypeVal).type; delete (yyvsp[-7].ValueList); CHECK_FOR_ERROR ;} break; - case 217: -#line 2410 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 229: +#line 2460 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.TermInstVal) = new UnwindInst(); CHECK_FOR_ERROR ;} break; - case 218: -#line 2414 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 230: +#line 2464 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.TermInstVal) = new UnreachableInst(); CHECK_FOR_ERROR ;} break; - case 219: -#line 2421 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 231: +#line 2471 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.JumpTable) = (yyvsp[-5].JumpTable); - Constant *V = cast<Constant>(getValNonImprovising((yyvsp[-4].PrimType), (yyvsp[-3].ValIDVal))); + Constant *V = cast<Constant>(getValNonImprovising((yyvsp[-4].TypeVal).type->get(), (yyvsp[-3].ValIDVal))); CHECK_FOR_ERROR if (V == 0) GEN_ERROR("May only switch on a constant pool value!"); @@ -4783,11 +4883,11 @@ yyreduce: ;} break; - case 220: -#line 2432 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 232: +#line 2482 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.JumpTable) = new std::vector<std::pair<Constant*, BasicBlock*> >(); - Constant *V = cast<Constant>(getValNonImprovising((yyvsp[-4].PrimType), (yyvsp[-3].ValIDVal))); + Constant *V = cast<Constant>(getValNonImprovising((yyvsp[-4].TypeVal).type->get(), (yyvsp[-3].ValIDVal))); CHECK_FOR_ERROR if (V == 0) @@ -4799,8 +4899,8 @@ yyreduce: ;} break; - case 221: -#line 2445 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 233: +#line 2495 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Is this definition named?? if so, assign the name... setValueName((yyvsp[0].InstVal), (yyvsp[-1].StrVal)); @@ -4811,21 +4911,21 @@ yyreduce: ;} break; - case 222: -#line 2454 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 234: +#line 2504 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Used for PHI nodes (yyval.PHIList) = new std::list<std::pair<Value*, BasicBlock*> >(); - Value* tmpVal = getVal(*(yyvsp[-5].TypeVal), (yyvsp[-3].ValIDVal)); + Value* tmpVal = getVal((yyvsp[-5].TypeVal).type->get(), (yyvsp[-3].ValIDVal)); CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal((yyvsp[-1].ValIDVal)); CHECK_FOR_ERROR (yyval.PHIList)->push_back(std::make_pair(tmpVal, tmpBB)); - delete (yyvsp[-5].TypeVal); + delete (yyvsp[-5].TypeVal).type; ;} break; - case 223: -#line 2463 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 235: +#line 2513 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.PHIList) = (yyvsp[-6].PHIList); Value* tmpVal = getVal((yyvsp[-6].PHIList)->front().first->getType(), (yyvsp[-3].ValIDVal)); @@ -4836,16 +4936,16 @@ yyreduce: ;} break; - case 224: -#line 2473 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 236: +#line 2523 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { // Used for call statements, and memory insts... (yyval.ValueList) = new std::vector<Value*>(); (yyval.ValueList)->push_back((yyvsp[0].ValueVal)); ;} break; - case 225: -#line 2477 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 237: +#line 2527 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = (yyvsp[-2].ValueList); (yyvsp[-2].ValueList)->push_back((yyvsp[0].ValueVal)); @@ -4853,92 +4953,92 @@ yyreduce: ;} break; - case 227: -#line 2484 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 239: +#line 2534 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = 0; ;} break; - case 228: -#line 2486 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 240: +#line 2536 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR ;} break; - case 229: -#line 2490 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 241: +#line 2540 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR ;} break; - case 230: -#line 2495 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 242: +#line 2545 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if (!(*(yyvsp[-3].TypeVal))->isInteger() && !(*(yyvsp[-3].TypeVal))->isFloatingPoint() && - !isa<PackedType>((*(yyvsp[-3].TypeVal)).get())) + if (!(yyvsp[-3].TypeVal).type->get()->isInteger() && !(yyvsp[-3].TypeVal).type->get()->isFloatingPoint() && + !isa<PackedType>((yyvsp[-3].TypeVal).type->get())) GEN_ERROR( "Arithmetic operator requires integer, FP, or packed operands!"); - if (isa<PackedType>((*(yyvsp[-3].TypeVal)).get()) && + if (isa<PackedType>((yyvsp[-3].TypeVal).type->get()) && ((yyvsp[-4].BinaryOpVal).opcode == Instruction::URem || (yyvsp[-4].BinaryOpVal).opcode == Instruction::SRem || (yyvsp[-4].BinaryOpVal).opcode == Instruction::FRem)) GEN_ERROR("U/S/FRem not supported on packed types!"); // Upgrade the opcode from obsolete versions before we do anything with it. - sanitizeOpCode((yyvsp[-4].BinaryOpVal),*(yyvsp[-3].TypeVal)); + sanitizeOpcode((yyvsp[-4].BinaryOpVal),(yyvsp[-3].TypeVal).type->get()); CHECK_FOR_ERROR; - Value* val1 = getVal(*(yyvsp[-3].TypeVal), (yyvsp[-2].ValIDVal)); + Value* val1 = getVal((yyvsp[-3].TypeVal).type->get(), (yyvsp[-2].ValIDVal)); CHECK_FOR_ERROR - Value* val2 = getVal(*(yyvsp[-3].TypeVal), (yyvsp[0].ValIDVal)); + Value* val2 = getVal((yyvsp[-3].TypeVal).type->get(), (yyvsp[0].ValIDVal)); CHECK_FOR_ERROR (yyval.InstVal) = BinaryOperator::create((yyvsp[-4].BinaryOpVal).opcode, val1, val2); if ((yyval.InstVal) == 0) GEN_ERROR("binary operator returned null!"); - delete (yyvsp[-3].TypeVal); + delete (yyvsp[-3].TypeVal).type; ;} break; - case 231: -#line 2517 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 243: +#line 2567 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if (!(*(yyvsp[-3].TypeVal))->isIntegral()) { - if (!isa<PackedType>((yyvsp[-3].TypeVal)->get()) || - !cast<PackedType>((yyvsp[-3].TypeVal)->get())->getElementType()->isIntegral()) + if (!(yyvsp[-3].TypeVal).type->get()->isIntegral()) { + if (!isa<PackedType>((yyvsp[-3].TypeVal).type->get()) || + !cast<PackedType>((yyvsp[-3].TypeVal).type->get())->getElementType()->isIntegral()) GEN_ERROR("Logical operator requires integral operands!"); } - Value* tmpVal1 = getVal(*(yyvsp[-3].TypeVal), (yyvsp[-2].ValIDVal)); + Value* tmpVal1 = getVal((yyvsp[-3].TypeVal).type->get(), (yyvsp[-2].ValIDVal)); CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*(yyvsp[-3].TypeVal), (yyvsp[0].ValIDVal)); + Value* tmpVal2 = getVal((yyvsp[-3].TypeVal).type->get(), (yyvsp[0].ValIDVal)); CHECK_FOR_ERROR (yyval.InstVal) = BinaryOperator::create((yyvsp[-4].BinaryOpVal).opcode, tmpVal1, tmpVal2); if ((yyval.InstVal) == 0) GEN_ERROR("binary operator returned null!"); - delete (yyvsp[-3].TypeVal); + delete (yyvsp[-3].TypeVal).type; ;} break; - case 232: -#line 2532 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 244: +#line 2582 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if(isa<PackedType>((*(yyvsp[-3].TypeVal)).get())) { + if(isa<PackedType>((yyvsp[-3].TypeVal).type->get())) { GEN_ERROR( "PackedTypes currently not supported in setcc instructions!"); } - Value* tmpVal1 = getVal(*(yyvsp[-3].TypeVal), (yyvsp[-2].ValIDVal)); + Value* tmpVal1 = getVal((yyvsp[-3].TypeVal).type->get(), (yyvsp[-2].ValIDVal)); CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*(yyvsp[-3].TypeVal), (yyvsp[0].ValIDVal)); + Value* tmpVal2 = getVal((yyvsp[-3].TypeVal).type->get(), (yyvsp[0].ValIDVal)); CHECK_FOR_ERROR (yyval.InstVal) = new SetCondInst((yyvsp[-4].BinaryOpVal).opcode, tmpVal1, tmpVal2); if ((yyval.InstVal) == 0) GEN_ERROR("binary operator returned null!"); - delete (yyvsp[-3].TypeVal); + delete (yyvsp[-3].TypeVal).type; ;} break; - case 233: -#line 2546 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 245: +#line 2596 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { std::cerr << "WARNING: Use of eliminated 'not' instruction:" << " Replacing with 'xor'.\n"; @@ -4954,35 +5054,53 @@ yyreduce: ;} break; - case 234: -#line 2559 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 246: +#line 2609 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[0].ValueVal)->getType() != Type::UByteTy) GEN_ERROR("Shift amount must be ubyte!"); if (!(yyvsp[-2].ValueVal)->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); // Handle opcode upgrade situations - sanitizeOpCode((yyvsp[-3].OtherOpVal), (yyvsp[-2].ValueVal)->getType()); + sanitizeOpcode((yyvsp[-3].OtherOpVal), (yyvsp[-2].ValueVal)->getType()); CHECK_FOR_ERROR; (yyval.InstVal) = new ShiftInst((yyvsp[-3].OtherOpVal).opcode, (yyvsp[-2].ValueVal), (yyvsp[0].ValueVal)); CHECK_FOR_ERROR ;} break; - case 235: -#line 2570 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 247: +#line 2620 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if (!(yyvsp[0].TypeVal)->get()->isFirstClassType()) - GEN_ERROR("cast instruction to a non-primitive type: '" + - (yyvsp[0].TypeVal)->get()->getDescription() + "'!"); - (yyval.InstVal) = new CastInst((yyvsp[-2].ValueVal), *(yyvsp[0].TypeVal)); - delete (yyvsp[0].TypeVal); - CHECK_FOR_ERROR + Value* Val = (yyvsp[-2].ValueVal); + const Type* Ty = (yyvsp[0].TypeVal).type->get(); + if (!Val->getType()->isFirstClassType()) + GEN_ERROR("cast from a non-primitive type: '" + + Val->getType()->getDescription() + "'!"); + if (!Ty->isFirstClassType()) + GEN_ERROR("cast to a non-primitive type: '" + Ty->getDescription() +"'!"); + + if ((yyvsp[-3].CastOpVal).obsolete) { + if (Ty == Type::BoolTy) { + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + (yyval.InstVal) = new SetCondInst(Instruction::SetNE, (yyvsp[-2].ValueVal), + Constant::getNullValue((yyvsp[-2].ValueVal)->getType())); + } else if (Val->getType()->isFloatingPoint() && isa<PointerType>(Ty)) { + CastInst *CI = new FPToUIInst(Val, Type::ULongTy); + (yyval.InstVal) = new IntToPtrInst(CI, Ty); + } else { + (yyval.InstVal) = CastInst::createInferredCast(Val, Ty); + } + } else { + (yyval.InstVal) = CastInst::create((yyvsp[-3].CastOpVal).opcode, (yyvsp[-2].ValueVal), (yyvsp[0].TypeVal).type->get()); + } + delete (yyvsp[0].TypeVal).type; ;} break; - case 236: -#line 2578 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 248: +#line 2646 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if ((yyvsp[-4].ValueVal)->getType() != Type::BoolTy) GEN_ERROR("select condition must be boolean!"); @@ -4993,18 +5111,18 @@ yyreduce: ;} break; - case 237: -#line 2586 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 249: +#line 2654 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { NewVarArgs = true; - (yyval.InstVal) = new VAArgInst((yyvsp[-2].ValueVal), *(yyvsp[0].TypeVal)); - delete (yyvsp[0].TypeVal); + (yyval.InstVal) = new VAArgInst((yyvsp[-2].ValueVal), (yyvsp[0].TypeVal).type->get()); + delete (yyvsp[0].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 238: -#line 2592 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 250: +#line 2660 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { ObsoleteVarArgs = true; const Type* ArgTy = (yyvsp[-2].ValueVal)->getType(); @@ -5021,14 +5139,14 @@ yyreduce: CallInst* bar = new CallInst(NF, (yyvsp[-2].ValueVal)); CurBB->getInstList().push_back(bar); CurBB->getInstList().push_back(new StoreInst(bar, foo)); - (yyval.InstVal) = new VAArgInst(foo, *(yyvsp[0].TypeVal)); - delete (yyvsp[0].TypeVal); + (yyval.InstVal) = new VAArgInst(foo, (yyvsp[0].TypeVal).type->get()); + delete (yyvsp[0].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 239: -#line 2612 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 251: +#line 2680 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { ObsoleteVarArgs = true; const Type* ArgTy = (yyvsp[-2].ValueVal)->getType(); @@ -5046,16 +5164,16 @@ yyreduce: CallInst* bar = new CallInst(NF, (yyvsp[-2].ValueVal)); CurBB->getInstList().push_back(bar); CurBB->getInstList().push_back(new StoreInst(bar, foo)); - Instruction* tmp = new VAArgInst(foo, *(yyvsp[0].TypeVal)); + Instruction* tmp = new VAArgInst(foo, (yyvsp[0].TypeVal).type->get()); CurBB->getInstList().push_back(tmp); (yyval.InstVal) = new LoadInst(foo); - delete (yyvsp[0].TypeVal); + delete (yyvsp[0].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 240: -#line 2635 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 252: +#line 2703 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!ExtractElementInst::isValidOperands((yyvsp[-2].ValueVal), (yyvsp[0].ValueVal))) GEN_ERROR("Invalid extractelement operands!"); @@ -5064,8 +5182,8 @@ yyreduce: ;} break; - case 241: -#line 2641 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 253: +#line 2709 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!InsertElementInst::isValidOperands((yyvsp[-4].ValueVal), (yyvsp[-2].ValueVal), (yyvsp[0].ValueVal))) GEN_ERROR("Invalid insertelement operands!"); @@ -5074,8 +5192,8 @@ yyreduce: ;} break; - case 242: -#line 2647 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 254: +#line 2715 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!ShuffleVectorInst::isValidOperands((yyvsp[-4].ValueVal), (yyvsp[-2].ValueVal), (yyvsp[0].ValueVal))) GEN_ERROR("Invalid shufflevector operands!"); @@ -5084,8 +5202,8 @@ yyreduce: ;} break; - case 243: -#line 2653 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 255: +#line 2721 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { const Type *Ty = (yyvsp[0].PHIList)->front().first->getType(); if (!Ty->isFirstClassType()) @@ -5103,13 +5221,13 @@ yyreduce: ;} break; - case 244: -#line 2668 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 256: +#line 2736 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const PointerType *PFTy; - const FunctionType *Ty; + const PointerType *PFTy = 0; + const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast<PointerType>((yyvsp[-4].TypeVal)->get())) || + if (!(PFTy = dyn_cast<PointerType>((yyvsp[-4].TypeVal).type->get())) || !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector<const Type*> ParamTypes; @@ -5122,10 +5240,11 @@ yyreduce: bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); - if (!(*(yyvsp[-4].TypeVal))->isFirstClassType() && *(yyvsp[-4].TypeVal) != Type::VoidTy) + if (!(yyvsp[-4].TypeVal).type->get()->isFirstClassType() && + (yyvsp[-4].TypeVal).type->get() != Type::VoidTy) GEN_ERROR("LLVM functions cannot return aggregate types!"); - Ty = FunctionType::get((yyvsp[-4].TypeVal)->get(), ParamTypes, isVarArg); + Ty = FunctionType::get((yyvsp[-4].TypeVal).type->get(), ParamTypes, isVarArg); PFTy = PointerType::get(Ty); } @@ -5160,92 +5279,92 @@ yyreduce: } cast<CallInst>((yyval.InstVal))->setTailCall((yyvsp[-6].BoolVal)); cast<CallInst>((yyval.InstVal))->setCallingConv((yyvsp[-5].UIntVal)); - delete (yyvsp[-4].TypeVal); + delete (yyvsp[-4].TypeVal).type; delete (yyvsp[-1].ValueList); CHECK_FOR_ERROR ;} break; - case 245: -#line 2727 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 257: +#line 2796 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.InstVal) = (yyvsp[0].InstVal); CHECK_FOR_ERROR ;} break; - case 246: -#line 2734 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 258: +#line 2803 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = (yyvsp[0].ValueList); CHECK_FOR_ERROR ;} break; - case 247: -#line 2737 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 259: +#line 2806 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.ValueList) = new std::vector<Value*>(); CHECK_FOR_ERROR ;} break; - case 248: -#line 2742 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 260: +#line 2811 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = true; CHECK_FOR_ERROR ;} break; - case 249: -#line 2746 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 261: +#line 2815 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { (yyval.BoolVal) = false; CHECK_FOR_ERROR ;} break; - case 250: -#line 2753 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 262: +#line 2822 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.InstVal) = new MallocInst(*(yyvsp[-1].TypeVal), 0, (yyvsp[0].UIntVal)); - delete (yyvsp[-1].TypeVal); + (yyval.InstVal) = new MallocInst((yyvsp[-1].TypeVal).type->get(), 0, (yyvsp[0].UIntVal)); + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 251: -#line 2758 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 263: +#line 2827 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - Value* tmpVal = getVal((yyvsp[-2].PrimType), (yyvsp[-1].ValIDVal)); + Value* tmpVal = getVal((yyvsp[-2].TypeVal).type->get(), (yyvsp[-1].ValIDVal)); CHECK_FOR_ERROR - (yyval.InstVal) = new MallocInst(*(yyvsp[-4].TypeVal), tmpVal, (yyvsp[0].UIntVal)); - delete (yyvsp[-4].TypeVal); + (yyval.InstVal) = new MallocInst((yyvsp[-4].TypeVal).type->get(), tmpVal, (yyvsp[0].UIntVal)); + delete (yyvsp[-4].TypeVal).type; ;} break; - case 252: -#line 2764 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 264: +#line 2833 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - (yyval.InstVal) = new AllocaInst(*(yyvsp[-1].TypeVal), 0, (yyvsp[0].UIntVal)); - delete (yyvsp[-1].TypeVal); + (yyval.InstVal) = new AllocaInst((yyvsp[-1].TypeVal).type->get(), 0, (yyvsp[0].UIntVal)); + delete (yyvsp[-1].TypeVal).type; CHECK_FOR_ERROR ;} break; - case 253: -#line 2769 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 265: +#line 2838 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - Value* tmpVal = getVal((yyvsp[-2].PrimType), (yyvsp[-1].ValIDVal)); + Value* tmpVal = getVal((yyvsp[-2].TypeVal).type->get(), (yyvsp[-1].ValIDVal)); CHECK_FOR_ERROR - (yyval.InstVal) = new AllocaInst(*(yyvsp[-4].TypeVal), tmpVal, (yyvsp[0].UIntVal)); - delete (yyvsp[-4].TypeVal); + (yyval.InstVal) = new AllocaInst((yyvsp[-4].TypeVal).type->get(), tmpVal, (yyvsp[0].UIntVal)); + delete (yyvsp[-4].TypeVal).type; ;} break; - case 254: -#line 2775 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 266: +#line 2844 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { if (!isa<PointerType>((yyvsp[0].ValueVal)->getType())) GEN_ERROR("Trying to free nonpointer type " + @@ -5255,65 +5374,65 @@ yyreduce: ;} break; - case 255: -#line 2783 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 267: +#line 2852 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if (!isa<PointerType>((yyvsp[-1].TypeVal)->get())) + if (!isa<PointerType>((yyvsp[-1].TypeVal).type->get())) GEN_ERROR("Can't load from nonpointer type: " + - (*(yyvsp[-1].TypeVal))->getDescription()); - if (!cast<PointerType>((yyvsp[-1].TypeVal)->get())->getElementType()->isFirstClassType()) + (yyvsp[-1].TypeVal).type->get()->getDescription()); + if (!cast<PointerType>((yyvsp[-1].TypeVal).type->get())->getElementType()->isFirstClassType()) GEN_ERROR("Can't load from pointer of non-first-class type: " + - (*(yyvsp[-1].TypeVal))->getDescription()); - Value* tmpVal = getVal(*(yyvsp[-1].TypeVal), (yyvsp[0].ValIDVal)); + (yyvsp[-1].TypeVal).type->get()->getDescription()); + Value* tmpVal = getVal((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].ValIDVal)); CHECK_FOR_ERROR (yyval.InstVal) = new LoadInst(tmpVal, "", (yyvsp[-3].BoolVal)); - delete (yyvsp[-1].TypeVal); + delete (yyvsp[-1].TypeVal).type; ;} break; - case 256: -#line 2795 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 268: +#line 2864 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - const PointerType *PT = dyn_cast<PointerType>((yyvsp[-1].TypeVal)->get()); + const PointerType *PT = dyn_cast<PointerType>((yyvsp[-1].TypeVal).type->get()); if (!PT) GEN_ERROR("Can't store to a nonpointer type: " + - (*(yyvsp[-1].TypeVal))->getDescription()); + ((yyvsp[-1].TypeVal).type->get())->getDescription()); const Type *ElTy = PT->getElementType(); if (ElTy != (yyvsp[-3].ValueVal)->getType()) GEN_ERROR("Can't store '" + (yyvsp[-3].ValueVal)->getType()->getDescription() + "' into space of type '" + ElTy->getDescription() + "'!"); - Value* tmpVal = getVal(*(yyvsp[-1].TypeVal), (yyvsp[0].ValIDVal)); + Value* tmpVal = getVal((yyvsp[-1].TypeVal).type->get(), (yyvsp[0].ValIDVal)); CHECK_FOR_ERROR (yyval.InstVal) = new StoreInst((yyvsp[-3].ValueVal), tmpVal, (yyvsp[-5].BoolVal)); - delete (yyvsp[-1].TypeVal); + delete (yyvsp[-1].TypeVal).type; ;} break; - case 257: -#line 2810 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" + case 269: +#line 2879 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" { - if (!isa<PointerType>((yyvsp[-2].TypeVal)->get())) + if (!isa<PointerType>((yyvsp[-2].TypeVal).type->get())) GEN_ERROR("getelementptr insn requires pointer operand!"); // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte struct // indices to uint struct indices for compatibility. generic_gep_type_iterator<std::vector<Value*>::iterator> - GTI = gep_type_begin((yyvsp[-2].TypeVal)->get(), (yyvsp[0].ValueList)->begin(), (yyvsp[0].ValueList)->end()), - GTE = gep_type_end((yyvsp[-2].TypeVal)->get(), (yyvsp[0].ValueList)->begin(), (yyvsp[0].ValueList)->end()); + GTI = gep_type_begin((yyvsp[-2].TypeVal).type->get(), (yyvsp[0].ValueList)->begin(), (yyvsp[0].ValueList)->end()), + GTE = gep_type_end((yyvsp[-2].TypeVal).type->get(), (yyvsp[0].ValueList)->begin(), (yyvsp[0].ValueList)->end()); for (unsigned i = 0, e = (yyvsp[0].ValueList)->size(); i != e && GTI != GTE; ++i, ++GTI) if (isa<StructType>(*GTI)) // Only change struct indices if (ConstantInt *CUI = dyn_cast<ConstantInt>((*(yyvsp[0].ValueList))[i])) if (CUI->getType() == Type::UByteTy) (*(yyvsp[0].ValueList))[i] = ConstantExpr::getCast(CUI, Type::UIntTy); - if (!GetElementPtrInst::getIndexedType(*(yyvsp[-2].TypeVal), *(yyvsp[0].ValueList), true)) + if (!GetElementPtrInst::getIndexedType((yyvsp[-2].TypeVal).type->get(), *(yyvsp[0].ValueList), true)) GEN_ERROR("Invalid getelementptr indices for type '" + - (*(yyvsp[-2].TypeVal))->getDescription()+ "'!"); - Value* tmpVal = getVal(*(yyvsp[-2].TypeVal), (yyvsp[-1].ValIDVal)); + (yyvsp[-2].TypeVal).type->get()->getDescription()+ "'!"); + Value* tmpVal = getVal((yyvsp[-2].TypeVal).type->get(), (yyvsp[-1].ValIDVal)); CHECK_FOR_ERROR (yyval.InstVal) = new GetElementPtrInst(tmpVal, *(yyvsp[0].ValueList)); - delete (yyvsp[-2].TypeVal); + delete (yyvsp[-2].TypeVal).type; delete (yyvsp[0].ValueList); ;} break; @@ -5323,7 +5442,7 @@ yyreduce: } /* Line 1126 of yacc.c. */ -#line 5327 "llvmAsmParser.tab.c" +#line 5446 "llvmAsmParser.tab.c" yyvsp -= yylen; yyssp -= yylen; @@ -5591,7 +5710,7 @@ yyreturn: } -#line 2836 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" +#line 2905 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" void llvm::GenerateError(const std::string &message, int LineNo) { diff --git a/lib/AsmParser/llvmAsmParser.h.cvs b/lib/AsmParser/llvmAsmParser.h.cvs index eb8e897589..d303bf5ddd 100644 --- a/lib/AsmParser/llvmAsmParser.h.cvs +++ b/lib/AsmParser/llvmAsmParser.h.cvs @@ -128,18 +128,29 @@ LOAD = 354, STORE = 355, GETELEMENTPTR = 356, - PHI_TOK = 357, - CAST = 358, - SELECT = 359, - SHL = 360, - LSHR = 361, - ASHR = 362, - VAARG = 363, - EXTRACTELEMENT = 364, - INSERTELEMENT = 365, - SHUFFLEVECTOR = 366, - VAARG_old = 367, - VANEXT_old = 368 + TRUNC = 357, + ZEXT = 358, + SEXT = 359, + FPTRUNC = 360, + FPEXT = 361, + BITCAST = 362, + UITOFP = 363, + SITOFP = 364, + FPTOUI = 365, + FPTOSI = 366, + INTTOPTR = 367, + PTRTOINT = 368, + PHI_TOK = 369, + SELECT = 370, + SHL = 371, + LSHR = 372, + ASHR = 373, + VAARG = 374, + EXTRACTELEMENT = 375, + INSERTELEMENT = 376, + SHUFFLEVECTOR = 377, + VAARG_old = 378, + VANEXT_old = 379 }; #endif /* Tokens. */ @@ -242,40 +253,50 @@ #define LOAD 354 #define STORE 355 #define GETELEMENTPTR 356 -#define PHI_TOK 357 -#define CAST 358 -#define SELECT 359 -#define SHL 360 -#define LSHR 361 -#define ASHR 362 -#define VAARG 363 -#define EXTRACTELEMENT 364 -#define INSERTELEMENT 365 -#define SHUFFLEVECTOR 366 -#define VAARG_old 367 -#define VANEXT_old 368 +#define TRUNC 357 +#define ZEXT 358 +#define SEXT 359 +#define FPTRUNC 360 +#define FPEXT 361 +#define BITCAST 362 +#define UITOFP 363 +#define SITOFP 364 +#define FPTOUI 365 +#define FPTOSI 366 +#define INTTOPTR 367 +#define PTRTOINT 368 +#define PHI_TOK 369 +#define SELECT 370 +#define SHL 371 +#define LSHR 372 +#define ASHR 373 +#define VAARG 374 +#define EXTRACTELEMENT 375 +#define INSERTELEMENT 376 +#define SHUFFLEVECTOR 377 +#define VAARG_old 378 +#define VANEXT_old 379 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 1040 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y" +#line 1040 "/proj/llvm/llvm-1/lib/AsmParser/llvmAsmParser.y" typedef union YYSTYPE { llvm::Module *ModuleVal; llvm::Function *FunctionVal; - std::pair<llvm::PATypeHolder*, char*> *ArgVal; + std::pair<TypeInfo, char*> *ArgVal; llvm::BasicBlock *BasicBlockVal; llvm::TerminatorInst *TermInstVal; llvm::Instruction *InstVal; llvm::Constant *ConstVal; - const llvm::Type *PrimType; - llvm::PATypeHolder *TypeVal; + TypeInfo TypeVal; llvm::Value *ValueVal; - std::vector<std::pair<llvm::PATypeHolder*,char*> > *ArgList; + std::vector<std::pair<TypeInfo,char*> >*ArgList; std::vector<llvm::Value*> *ValueList; - std::list<llvm::PATypeHolder> *TypeList; + std::list<TypeInfo> *TypeList; // Represent the RHS of PHI node std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *PHIList; @@ -296,11 +317,12 @@ typedef union YYSTYPE { BinaryOpInfo BinaryOpVal; TermOpInfo TermOpVal; MemOpInfo MemOpVal; + CastOpInfo CastOpVal; OtherOpInfo OtherOpVal; llvm::Module::Endianness Endianness; } YYSTYPE; /* Line 1447 of yacc.c. */ -#line 304 "llvmAsmParser.tab.h" +#line 326 "llvmAsmParser.tab.h" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 806372ae87..202c384129 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -824,14 +824,14 @@ static PATypeHolder HandleUpRefs(const Type *ty) { /// instruction. This function handles converting div -> [usf]div appropriately. /// @brief Convert obsolete BinaryOps opcodes to new values static void -sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const Type *Ty) +sanitizeOpcode(OpcodeInfo<Instruction::BinaryOps> &OI, const Type *Ty) { // If its not obsolete, don't do anything if (!OI.obsolete) return; // If its a packed type we want to use the element type - if (const PackedType* PTy = dyn_cast<PackedType>(Ty)) + if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) Ty = PTy->getElementType(); // Depending on the opcode .. @@ -857,11 +857,11 @@ sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const Type *Ty) OI.obsolete = false; } -/// This function is similar to the previous overload of sanitizeOpCode but +/// This function is similar to the previous overload of sanitizeOpcode but /// operates on Instruction::OtherOps instead of Instruction::BinaryOps. /// @brief Convert obsolete OtherOps opcodes to new values static void -sanitizeOpCode(OpcodeInfo<Instruction::OtherOps> &OI, const Type *Ty) +sanitizeOpcode(OpcodeInfo<Instruction::OtherOps> &OI, const Type *Ty) { // If its not obsolete, don't do anything if (!OI.obsolete) @@ -1072,6 +1072,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { BinaryOpInfo BinaryOpVal; TermOpInfo TermOpVal; MemOpInfo MemOpVal; + CastOpInfo CastOpVal; OtherOpInfo OtherOpVal; llvm::Module::Endianness Endianness; } @@ -1147,9 +1148,14 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { // Memory Instructions %token <MemOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR +// Cast Operators +%type <CastOpVal> CastOps +%token <CastOpVal> TRUNC ZEXT SEXT FPTRUNC FPEXT BITCAST +%token <CastOpVal> UITOFP SITOFP FPTOUI FPTOSI INTTOPTR PTRTOINT + // Other Operators %type <OtherOpVal> ShiftOps -%token <OtherOpVal> PHI_TOK CAST SELECT SHL LSHR ASHR VAARG +%token <OtherOpVal> PHI_TOK SELECT SHL LSHR ASHR VAARG %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR %token VAARG_old VANEXT_old //OBSOLETE @@ -1182,8 +1188,9 @@ EINT64VAL : EUINT64VAL { ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM; LogicalOps : AND | OR | XOR; SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE; - -ShiftOps : SHL | LSHR | ASHR; +CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST | + UITOFP | SITOFP | FPTOUI | FPTOSI | INTTOPTR | PTRTOINT; +ShiftOps : SHL | LSHR | ASHR; // These are some types that allow classification if we only want a particular // thing... for example, only a signed, unsigned, or integral type. @@ -1676,16 +1683,31 @@ ConstVal : SIntType EINT64VAL { // integral constants }; -ConstExpr: CAST '(' ConstVal TO Types ')' { - if (!$3->getType()->isFirstClassType()) +ConstExpr: CastOps '(' ConstVal TO Types ')' { + Constant *Val = $3; + const Type *Ty = $5.type->get(); + if (!Val->getType()->isFirstClassType()) GEN_ERROR("cast constant expression from a non-primitive type: '" + - $3->getType()->getDescription() + "'!"); - if (!$5.type->get()->isFirstClassType()) + Val->getType()->getDescription() + "'!"); + if (!Ty->isFirstClassType()) GEN_ERROR("cast constant expression to a non-primitive type: '" + - $5.type->get()->getDescription() + "'!"); - $$ = ConstantExpr::getCast($3, $5.type->get()); + Ty->getDescription() + "'!"); + if ($1.obsolete) { + if (Ty == Type::BoolTy) { + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + $$ = ConstantExpr::get(Instruction::SetNE, Val, + Constant::getNullValue(Val->getType())); + } else if (Val->getType()->isFloatingPoint() && isa<PointerType>(Ty)) { + Constant *CE = ConstantExpr::getFPToUI(Val, Type::ULongTy); + $$ = ConstantExpr::getIntToPtr(CE, Ty); + } else { + $$ = ConstantExpr::getCast(Val, Ty); + } + } else { + $$ = ConstantExpr::getCast($1.opcode, $3, $5.type->get()); + } delete $5.type; - CHECK_FOR_ERROR } | GETELEMENTPTR '(' ConstVal IndexList ')' { if (!isa<PointerType>($3->getType())) @@ -1732,7 +1754,7 @@ ConstExpr: CAST '(' ConstVal TO Types ')' { GEN_ERROR("Binary operator types must match!"); // First, make sure we're dealing with the right opcode by upgrading from // obsolete versions. - sanitizeOpCode($1,$3->getType()); + sanitizeOpcode($1, $3->getType()); CHECK_FOR_ERROR; // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs. @@ -1777,7 +1799,7 @@ ConstExpr: CAST '(' ConstVal TO Types ')' { if (!$3->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); // Handle opcode upgrade situations - sanitizeOpCode($1, $3->getType()); + sanitizeOpcode($1, $3->getType()); CHECK_FOR_ERROR; $$ = ConstantExpr::get($1.opcode, $3, $5); CHECK_FOR_ERROR @@ -2296,6 +2318,10 @@ BasicBlock : InstructionList OptAssign BBTerminatorInst { }; InstructionList : InstructionList Inst { + if (CastInst *CI1 = dyn_cast<CastInst>($2)) + if (CastInst *CI2 = dyn_cast<CastInst>(CI1->getOperand(0))) + if (CI2->getParent() == 0) + $1->getInstList().push_back(CI2); $1->getInstList().push_back($2); $$ = $1; CHECK_FOR_ERROR @@ -2527,7 +2553,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { $1.opcode == Instruction::FRem)) GEN_ERROR("U/S/FRem not supported on packed types!"); // Upgrade the opcode from obsolete versions before we do anything with it. - sanitizeOpCode($1,$2.type->get()); + sanitizeOpcode($1,$2.type->get()); CHECK_FOR_ERROR; Value* val1 = getVal($2.type->get(), $3); CHECK_FOR_ERROR @@ -2586,18 +2612,36 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { if (!$2->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); // Handle opcode upgrade situations - sanitizeOpCode($1, $2->getType()); + sanitizeOpcode($1, $2->getType()); CHECK_FOR_ERROR; $$ = new ShiftInst($1.opcode, $2, $4); CHECK_FOR_ERROR } - | CAST ResolvedVal TO Types { - if (!$4.type->get()->isFirstClassType()) - GEN_ERROR("cast instruction to a non-primitive type: '" + - $4.type->get()->getDescription() + "'!"); - $$ = new CastInst($2, $4.type->get()); + | CastOps ResolvedVal TO Types { + Value* Val = $2; + const Type* Ty = $4.type->get(); + if (!Val->getType()->isFirstClassType()) + GEN_ERROR("cast from a non-primitive type: '" + + Val->getType()->getDescription() + "'!"); + if (!Ty->isFirstClassType()) + GEN_ERROR("cast to a non-primitive type: '" + Ty->getDescription() +"'!"); + + if ($1.obsolete) { + if (Ty == Type::BoolTy) { + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + $$ = new SetCondInst(Instruction::SetNE, $2, + Constant::getNullValue($2->getType())); + } else if (Val->getType()->isFloatingPoint() && isa<PointerType>(Ty)) { + CastInst *CI = new FPToUIInst(Val, Type::ULongTy); + $$ = new IntToPtrInst(CI, Ty); + } else { + $$ = CastInst::createInferredCast(Val, Ty); + } + } else { + $$ = CastInst::create($1.opcode, $2, $4.type->get()); + } delete $4.type; - CHECK_FOR_ERROR } | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { if ($2->getType() != Type::BoolTy) diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs index 4611262b01..202c384129 100644 --- a/lib/AsmParser/llvmAsmParser.y.cvs +++ b/lib/AsmParser/llvmAsmParser.y.cvs @@ -83,8 +83,8 @@ static struct PerModuleInfo { Module *CurrentModule; std::map<const Type *, ValueList> Values; // Module level numbered definitions std::map<const Type *,ValueList> LateResolveValues; - std::vector<PATypeHolder> Types; - std::map<ValID, PATypeHolder> LateResolveTypes; + std::vector<TypeInfo> Types; + std::map<ValID, TypeInfo> LateResolveTypes; /// PlaceHolderInfo - When temporary placeholder objects are created, remember /// how they were referenced and on which line of the input they came from so @@ -217,7 +217,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { case ValID::NumberVal: // Is it a numbered definition? // Module constants occupy the lowest numbered slots... if ((unsigned)D.Num < CurModule.Types.size()) - return CurModule.Types[(unsigned)D.Num]; + return CurModule.Types[(unsigned)D.Num].type->get(); break; case ValID::NameVal: // Is it a named definition? if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) { @@ -247,13 +247,15 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { } } - std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D); + std::map<ValID, TypeInfo>::iterator I =CurModule.LateResolveTypes.find(D); if (I != CurModule.LateResolveTypes.end()) - return I->second; + return I->second.type->get(); - Type *Typ = OpaqueType::get(); - CurModule.LateResolveTypes.insert(std::make_pair(D, Typ)); - return Typ; + TypeInfo TI; + TI.type = new PATypeHolder(OpaqueType::get()); + TI.signedness = isSignless; + CurModule.LateResolveTypes.insert(std::make_pair(D, TI)); + return TI.type->get(); } static Value *lookupInSymbolTable(const Type *Ty, const std::string &Name) { @@ -557,10 +559,10 @@ static void ResolveTypeTo(char *Name, const Type *ToTy) { if (Name) D = ValID::create(Name); else D = ValID::create((int)CurModule.Types.size()); - std::map<ValID, PATypeHolder>::iterator I = + std::map<ValID, TypeInfo>::iterator I = CurModule.LateResolveTypes.find(D); if (I != CurModule.LateResolveTypes.end()) { - ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); + ((DerivedType*)I->second.type->get())->refineAbstractTypeTo(ToTy); CurModule.LateResolveTypes.erase(I); } } @@ -822,15 +824,14 @@ static PATypeHolder HandleUpRefs(const Type *ty) { /// instruction. This function handles converting div -> [usf]div appropriately. /// @brief Convert obsolete BinaryOps opcodes to new values static void -sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy) +sanitizeOpcode(OpcodeInfo<Instruction::BinaryOps> &OI, const Type *Ty) { // If its not obsolete, don't do anything if (!OI.obsolete) return; // If its a packed type we want to use the element type - const Type* Ty = PATy; - if (const PackedType* PTy = dyn_cast<PackedType>(Ty)) + if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) Ty = PTy->getElementType(); // Depending on the opcode .. @@ -856,17 +857,16 @@ sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy) OI.obsolete = false; } -/// This function is similar to the previous overload of sanitizeOpCode but +/// This function is similar to the previous overload of sanitizeOpcode but /// operates on Instruction::OtherOps instead of Instruction::BinaryOps. /// @brief Convert obsolete OtherOps opcodes to new values static void -sanitizeOpCode(OpcodeInfo<Instruction::OtherOps> &OI, const PATypeHolder& PATy) +sanitizeOpcode(OpcodeInfo<Instruction::OtherOps> &OI, const Type *Ty) { // If its not obsolete, don't do anything if (!OI.obsolete) return; - const Type* Ty = PATy; // type conversion switch (OI.opcode) { default: GenerateError("Invalid obsolete opcode (check Lexer.l)"); @@ -1040,19 +1040,18 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %union { llvm::Module *ModuleVal; llvm::Function *FunctionVal; - std::pair<llvm::PATypeHolder*, char*> *ArgVal; + std::pair<TypeInfo, char*> *ArgVal; llvm::BasicBlock *BasicBlockVal; llvm::TerminatorInst *TermInstVal; llvm::Instruction *InstVal; llvm::Constant *ConstVal; - const llvm::Type *PrimType; - llvm::PATypeHolder *TypeVal; + TypeInfo TypeVal; llvm::Value *ValueVal; - std::vector<std::pair<llvm::PATypeHolder*,char*> > *ArgList; + std::vector<std::pair<TypeInfo,char*> >*ArgList; std::vector<llvm::Value*> *ValueList; - std::list<llvm::PATypeHolder> *TypeList; + std::list<TypeInfo> *TypeList; // Represent the RHS of PHI node std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *PHIList; @@ -1073,6 +1072,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { BinaryOpInfo BinaryOpVal; TermOpInfo TermOpVal; MemOpInfo MemOpVal; + CastOpInfo CastOpVal; OtherOpInfo OtherOpVal; llvm::Module::Endianness Endianness; } @@ -1117,9 +1117,9 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { // Built in types... %type <TypeVal> Types TypesV UpRTypes UpRTypesV -%type <PrimType> SIntType UIntType IntType FPType PrimType // Classifications -%token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG -%token <PrimType> FLOAT DOUBLE TYPE LABEL +%type <TypeVal> SIntType UIntType IntType FPType PrimType // Classifications +%token <TypeVal> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG +%token <TypeVal> FLOAT DOUBLE TYPE LABEL %token <StrVal> VAR_ID LABELSTR STRINGCONSTANT %type <StrVal> Name OptName OptAssign @@ -1148,9 +1148,14 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { // Memory Instructions %token <MemOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR +// Cast Operators +%type <CastOpVal> CastOps +%token <CastOpVal> TRUNC ZEXT SEXT FPTRUNC FPEXT BITCAST +%token <CastOpVal> UITOFP SITOFP FPTOUI FPTOSI INTTOPTR PTRTOINT + // Other Operators %type <OtherOpVal> ShiftOps -%token <OtherOpVal> PHI_TOK CAST SELECT SHL LSHR ASHR VAARG +%token <OtherOpVal> PHI_TOK SELECT SHL LSHR ASHR VAARG %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR %token VAARG_old VANEXT_old //OBSOLETE @@ -1183,8 +1188,9 @@ EINT64VAL : EUINT64VAL { ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM; LogicalOps : AND | OR | XOR; SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE; - -ShiftOps : SHL | LSHR | ASHR; +CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST | + UITOFP | SITOFP | FPTOUI | FPTOSI | INTTOPTR | PTRTOINT; +ShiftOps : SHL | LSHR | ASHR; // These are some types that allow classification if we only want a particular // thing... for example, only a signed, unsigned, or integral type. @@ -1279,15 +1285,22 @@ GlobalVarAttribute : SectionString { // // TypesV includes all of 'Types', but it also includes the void type. -TypesV : Types | VOID { $$ = new PATypeHolder($1); }; -UpRTypesV : UpRTypes | VOID { $$ = new PATypeHolder($1); }; +TypesV : Types | VOID { + $$.type = new PATypeHolder($1.type->get()); + $$.signedness = $1.signedness; +}; +UpRTypesV : UpRTypes | VOID { + $$.type = new PATypeHolder($1.type->get()); + $$.signedness = $1.signedness; +}; Types : UpRTypes { if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); + GEN_ERROR("Invalid upreference in type: " + + ($1.type->get())->getDescription()); $$ = $1; CHECK_FOR_ERROR - }; +}; // Derived types are added later... @@ -1295,17 +1308,19 @@ Types : UpRTypes { PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ; PrimType : LONG | ULONG | FLOAT | DOUBLE | TYPE | LABEL; UpRTypes : OPAQUE { - $$ = new PATypeHolder(OpaqueType::get()); + $$.type = new PATypeHolder(OpaqueType::get()); + $$.signedness = isSignless; CHECK_FOR_ERROR } | PrimType { - $$ = new PATypeHolder($1); + $$ = $1; CHECK_FOR_ERROR }; UpRTypes : SymbolicValueRef { // Named types are also simple types... const Type* tmp = getTypeVal($1); CHECK_FOR_ERROR - $$ = new PATypeHolder(tmp); + $$.type = new PATypeHolder(tmp); + $$.signedness = isSignless; }; // Include derived types in the Types production. @@ -1314,59 +1329,69 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference if ($2 > (uint64_t)~0U) GEN_ERROR("Value out of range!"); OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector... - $$ = new PATypeHolder(OT); + $$.type = new PATypeHolder(OT); + $$.signedness = isSignless; UR_OUT("New Upreference!\n"); CHECK_FOR_ERROR } | UpRTypesV '(' ArgTypeListI ')' { // Function derived type? std::vector<const Type*> Params; - for (std::list<llvm::PATypeHolder>::iterator I = $3->begin(), + for (std::list<TypeInfo>::iterator I = $3->begin(), E = $3->end(); I != E; ++I) - Params.push_back(*I); + Params.push_back(I->type->get()); bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - $$ = new PATypeHolder(HandleUpRefs(FunctionType::get(*$1,Params,isVarArg))); + $$.type = new PATypeHolder(HandleUpRefs( + FunctionType::get($1.type->get(),Params,isVarArg))); + $$.signedness = isSignless; delete $3; // Delete the argument list - delete $1; // Delete the return type handle + delete $1.type; CHECK_FOR_ERROR } | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type? - $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2))); - delete $4; + $$.type = new PATypeHolder(HandleUpRefs( + ArrayType::get($4.type->get(), (unsigned)$2))); + $$.signedness = isSignless; + delete $4.type; CHECK_FOR_ERROR } | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type? - const llvm::Type* ElemTy = $4->get(); - if ((unsigned)$2 != $2) - GEN_ERROR("Unsigned result not equal to signed result"); - if (!ElemTy->isPrimitiveType()) - GEN_ERROR("Elemental type of a PackedType must be primitive"); - if (!isPowerOf2_32($2)) - GEN_ERROR("Vector length should be a power of 2!"); - $$ = new PATypeHolder(HandleUpRefs(PackedType::get(*$4, (unsigned)$2))); - delete $4; - CHECK_FOR_ERROR + const llvm::Type* ElemTy = $4.type->get(); + if ((unsigned)$2 != $2) + GEN_ERROR("Unsigned result not equal to signed result"); + if (!ElemTy->isPrimitiveType()) + GEN_ERROR("Elemental type of a PackedType must be primitive"); + if (!isPowerOf2_32($2)) + GEN_ERROR("Vector length should be a power of 2!"); + $$.type = new PATypeHolder(HandleUpRefs( + PackedType::get($4.type->get(), (unsigned)$2))); + $$.signedness = isSignless; + delete $4.type; + CHECK_FOR_ERROR } | '{' TypeListI '}' { // Structure type? std::vector<const Type*> Elements; - for (std::list<llvm::PATypeHolder>::iterator I = $2->begin(), + for (std::list<TypeInfo>::iterator I = $2->begin(), E = $2->end(); I != E; ++I) - Elements.push_back(*I); + Elements.push_back(I->type->get()); - $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); + $$.type = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); + $$.signedness = isSignless; delete $2; CHECK_FOR_ERROR } | '{' '}' { // Empty structure type? - $$ = new PATypeHolder(StructType::get(std::vector<const Type*>())); + $$.type = new PATypeHolder(StructType::get(std::vector<const Type*>())); + $$.signedness = isSignless; CHECK_FOR_ERROR } | UpRTypes '*' { // Pointer type? - if (*$1 == Type::LabelTy) + if ($1.type->get() == Type::LabelTy) GEN_ERROR("Cannot form a pointer to a basic block"); - $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1))); - delete $1; + $$.type = new PATypeHolder(HandleUpRefs(PointerType::get($1.type->get()))); + $$.signedness = $1.signedness; + delete $1.type; CHECK_FOR_ERROR }; @@ -1374,27 +1399,31 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference // declaration type lists // TypeListI : UpRTypes { - $$ = new std::list<PATypeHolder>(); - $$->push_back(*$1); delete $1; + $$ = new std::list<TypeInfo>(); + $$->push_back($1); CHECK_FOR_ERROR } | TypeListI ',' UpRTypes { - ($$=$1)->push_back(*$3); delete $3; + ($$=$1)->push_back($3); CHECK_FOR_ERROR }; // ArgTypeList - List of types for a function type declaration... ArgTypeListI : TypeListI | TypeListI ',' DOTDOTDOT { - ($$=$1)->push_back(Type::VoidTy); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); TI.signedness = isSignless; + ($$=$1)->push_back(TI); CHECK_FOR_ERROR } | DOTDOTDOT { - ($$ = new std::list<PATypeHolder>())->push_back(Type::VoidTy); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); TI.signedness = isSignless; + ($$ = new std::list<TypeInfo>())->push_back(TI); CHECK_FOR_ERROR } | /*empty*/ { - $$ = new std::list<PATypeHolder>(); + $$ = new std::list<TypeInfo>(); CHECK_FOR_ERROR }; @@ -1405,10 +1434,10 @@ ArgTypeListI : TypeListI // ResolvedVal, ValueRef and ConstValueRef productions. // ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr - const ArrayType *ATy = dyn_cast<ArrayType>($1->get()); + const ArrayType *ATy = dyn_cast<ArrayType>($1.type->get()); if (ATy == 0) GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'!"); + ($1.type->get())->getDescription() + "'!"); const Type *ETy = ATy->getElementType(); int NumElements = ATy->getNumElements(); @@ -1427,28 +1456,28 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr } $$ = ConstantArray::get(ATy, *$3); - delete $1; delete $3; + delete $1.type; delete $3; CHECK_FOR_ERROR } | Types '[' ']' { - const ArrayType *ATy = dyn_cast<ArrayType>($1->get()); + const ArrayType *ATy = dyn_cast<ArrayType>($1.type->get()); if (ATy == 0) GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'!"); + ($1.type->get())->getDescription() + "'!"); int NumElements = ATy->getNumElements(); if (NumElements != -1 && NumElements != 0) GEN_ERROR("Type mismatch: constant sized array initialized with 0" " arguments, but has size of " + itostr(NumElements) +"!"); $$ = ConstantArray::get(ATy, std::vector<Constant*>()); - delete $1; + delete $1.type; CHECK_FOR_ERROR } | Types 'c' STRINGCONSTANT { - const ArrayType *ATy = dyn_cast<ArrayType>($1->get()); + const ArrayType *ATy = dyn_cast<ArrayType>($1.type->get()); if (ATy == 0) GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'!"); + ($1.type->get())->getDescription() + "'!"); int NumElements = ATy->getNumElements(); const Type *ETy = ATy->getElementType(); @@ -1471,14 +1500,14 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr } free($3); $$ = ConstantArray::get(ATy, Vals); - delete $1; + delete $1.type; CHECK_FOR_ERROR } | Types '<' ConstVector '>' { // Nonempty unsized arr - const PackedType *PTy = dyn_cast<PackedType>($1->get()); + const PackedType *PTy = dyn_cast<PackedType>($1.type->get()); if (PTy == 0) GEN_ERROR("Cannot make packed constant with type: '" + - (*$1)->getDescription() + "'!"); + $1.type->get()->getDescription() + "'!"); const Type *ETy = PTy->getElementType(); int NumElements = PTy->getNumElements(); @@ -1497,14 +1526,14 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr } $$ = ConstantPacked::get(PTy, *$3); - delete $1; delete $3; + delete $1.type; delete $3; CHECK_FOR_ERROR } | Types '{' ConstVector '}' { - const StructType *STy = dyn_cast<StructType>($1->get()); + const StructType *STy = dyn_cast<StructType>($1.type->get()); if (STy == 0) GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'!"); + $1.type->get()->getDescription() + "'!"); if ($3->size() != STy->getNumContainedTypes()) GEN_ERROR("Illegal number of initializers for structure type!"); @@ -1518,39 +1547,39 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr " of structure initializer!"); $$ = ConstantStruct::get(STy, *$3); - delete $1; delete $3; + delete $1.type; delete $3; CHECK_FOR_ERROR } | Types '{' '}' { - const StructType *STy = dyn_cast<StructType>($1->get()); + const StructType *STy = dyn_cast<StructType>($1.type->get()); if (STy == 0) GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'!"); + $1.type->get()->getDescription() + "'!"); if (STy->getNumContainedTypes() != 0) GEN_ERROR("Illegal number of initializers for structure type!"); $$ = ConstantStruct::get(STy, std::vector<Constant*>()); - delete $1; + delete $1.type; CHECK_FOR_ERROR } | Types NULL_TOK { - const PointerType *PTy = dyn_cast<PointerType>($1->get()); + const PointerType *PTy = dyn_cast<PointerType>($1.type->get()); if (PTy == 0) GEN_ERROR("Cannot make null pointer constant with type: '" + - (*$1)->getDescription() + "'!"); + $1.type->get()->getDescription() + "'!"); $$ = ConstantPointerNull::get(PTy); - delete $1; + delete $1.type; CHECK_FOR_ERROR } | Types UNDEF { - $$ = UndefValue::get($1->get()); - delete $1; + $$ = UndefValue::get($1.type->get()); + delete $1.type; CHECK_FOR_ERROR } | Types SymbolicValueRef { - const PointerType *Ty = dyn_cast<PointerType>($1->get()); + const PointerType *Ty = dyn_cast<PointerType>($1.type->get()); if (Ty == 0) GEN_ERROR("Global const reference must be a pointer type!"); @@ -1607,35 +1636,35 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr } $$ = cast<GlobalValue>(V); - delete $1; // Free the type handle + delete $1.type; // Free the type handle CHECK_FOR_ERROR } | Types ConstExpr { - if ($1->get() != $2->getType()) + if ($1.type->get() != $2->getType()) GEN_ERROR("Mismatched types for constant expression!"); $$ = $2; - delete $1; + delete $1.type; CHECK_FOR_ERROR } | Types ZEROINITIALIZER { - const Type *Ty = $1->get(); + const Type *Ty = $1.type->get(); if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || isa<OpaqueType>(Ty)) GEN_ERROR("Cannot create a null initialized value of this type!"); $$ = Constant::getNullValue(Ty); - delete $1; + delete $1.type; CHECK_FOR_ERROR }; ConstVal : SIntType EINT64VAL { // integral constants - if (!ConstantInt::isValueValidForType($1, $2)) + if (!ConstantInt::isValueValidForType($1.type->get(), $2)) GEN_ERROR("Constant value doesn't fit in type!"); - $$ = ConstantInt::get($1, $2); + $$ = ConstantInt::get($1.type->get(), $2); CHECK_FOR_ERROR } | UIntType EUINT64VAL { // integral constants - if (!ConstantInt::isValueValidForType($1, $2)) + if (!ConstantInt::isValueValidForType($1.type->get(), $2)) GEN_ERROR("Constant value doesn't fit in type!"); - $$ = ConstantInt::get($1, $2); + $$ = ConstantInt::get($1.type->get(), $2); CHECK_FOR_ERROR } | BOOL TRUETOK { // Boolean constants @@ -1647,23 +1676,38 @@ ConstVal : SIntType EINT64VAL { // integral constants CHECK_FOR_ERROR } | FPType FPVAL { // Float & Double constants - if (!ConstantFP::isValueValidForType($1, $2)) + if (!ConstantFP::isValueValidForType($1.type->get(), $2)) GEN_ERROR("Floating point constant invalid for type!!"); - $$ = ConstantFP::get($1, $2); + $$ = ConstantFP::get($1.type->get(), $2); CHECK_FOR_ERROR }; -ConstExpr: CAST '(' ConstVal TO Types ')' { - if (!$3->getType()->isFirstClassType()) +ConstExpr: CastOps '(' ConstVal TO Types ')' { + Constant *Val = $3; + const Type *Ty = $5.type->get(); + if (!Val->getType()->isFirstClassType()) GEN_ERROR("cast constant expression from a non-primitive type: '" + - $3->getType()->getDescription() + "'!"); - if (!$5->get()->isFirstClassType()) + Val->getType()->getDescription() + "'!"); + if (!Ty->isFirstClassType()) GEN_ERROR("cast constant expression to a non-primitive type: '" + - $5->get()->getDescription() + "'!"); - $$ = ConstantExpr::getCast($3, $5->get()); - delete $5; - CHECK_FOR_ERROR + Ty->getDescription() + "'!"); + if ($1.obsolete) { + if (Ty == Type::BoolTy) { + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + $$ = ConstantExpr::get(Instruction::SetNE, Val, + Constant::getNullValue(Val->getType())); + } else if (Val->getType()->isFloatingPoint() && isa<PointerType>(Ty)) { + Constant *CE = ConstantExpr::getFPToUI(Val, Type::ULongTy); + $$ = ConstantExpr::getIntToPtr(CE, Ty); + } else { + $$ = ConstantExpr::getCast(Val, Ty); + } + } else { + $$ = ConstantExpr::getCast($1.opcode, $3, $5.type->get()); + } + delete $5.type; } | GETELEMENTPTR '(' ConstVal IndexList ')' { if (!isa<PointerType>($3->getType())) @@ -1710,7 +1754,7 @@ ConstExpr: CAST '(' ConstVal TO Types ')' { GEN_ERROR("Binary operator types must match!"); // First, make sure we're dealing with the right opcode by upgrading from // obsolete versions. - sanitizeOpCode($1,$3->getType()); + sanitizeOpcode($1, $3->getType()); CHECK_FOR_ERROR; // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs. @@ -1755,7 +1799,7 @@ ConstExpr: CAST '(' ConstVal TO Types ')' { if (!$3->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); // Handle opcode upgrade situations - sanitizeOpCode($1, $3->getType()); + sanitizeOpcode($1, $3->getType()); CHECK_FOR_ERROR; $$ = ConstantExpr::get($1.opcode, $3, $5); CHECK_FOR_ERROR @@ -1853,16 +1897,16 @@ ConstPool : ConstPool OptAssign TYPE TypesV { // If types are not resolved eagerly, then the two types will not be // determined to be the same type! // - ResolveTypeTo($2, *$4); + ResolveTypeTo($2, $4.type->get()); - if (!setTypeName(*$4, $2) && !$2) { + if (!setTypeName($4.type->get(), $2) && !$2) { CHECK_FOR_ERROR // If this is a named type that is not a redefinition, add it to the slot // table. - CurModule.Types.push_back(*$4); + CurModule.Types.push_back($4); + } else { + delete $4.type; } - - delete $4; CHECK_FOR_ERROR } | ConstPool FunctionProto { // Function prototypes can be in const pool @@ -1880,26 +1924,29 @@ ConstPool : ConstPool OptAssign TYPE TypesV { CurGV = 0; } | ConstPool OptAssign EXTERNAL GlobalType Types { - CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, *$5, 0); + CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, + $5.type->get(), 0); CHECK_FOR_ERROR - delete $5; + delete $5.type; } GlobalVarAttributes { CurGV = 0; CHECK_FOR_ERROR } | ConstPool OptAssign DLLIMPORT GlobalType Types { - CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, *$5, 0); + CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, + $5.type->get(), 0); CHECK_FOR_ERROR - delete $5; + delete $5.type; } GlobalVarAttributes { CurGV = 0; CHECK_FOR_ERROR } | ConstPool OptAssign EXTERN_WEAK GlobalType Types { CurGV = - ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, *$5, 0); + ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, + $5.type->get(), 0); CHECK_FOR_ERROR - delete $5; + delete $5.type; } GlobalVarAttributes { CurGV = 0; CHECK_FOR_ERROR @@ -1977,9 +2024,9 @@ Name : VAR_ID | STRINGCONSTANT; OptName : Name | /*empty*/ { $$ = 0; }; ArgVal : Types OptName { - if (*$1 == Type::VoidTy) + if ($1.type->get() == Type::VoidTy) GEN_ERROR("void typed arguments are invalid!"); - $$ = new std::pair<PATypeHolder*, char*>($1, $2); + $$ = new std::pair<TypeInfo, char*>($1, $2); CHECK_FOR_ERROR }; @@ -1990,7 +2037,7 @@ ArgListH : ArgListH ',' ArgVal { CHECK_FOR_ERROR } | ArgVal { - $$ = new std::vector<std::pair<PATypeHolder*,char*> >(); + $$ = new std::vector<std::pair<TypeInfo,char*> >(); $$->push_back(*$1); delete $1; CHECK_FOR_ERROR @@ -2002,13 +2049,18 @@ ArgList : ArgListH { } | ArgListH ',' DOTDOTDOT { $$ = $1; - $$->push_back(std::pair<PATypeHolder*, - char*>(new PATypeHolder(Type::VoidTy), 0)); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); + TI.signedness = isSignless; + $$->push_back(std::pair<TypeInfo,char*>(TI,(char*)0)); CHECK_FOR_ERROR } | DOTDOTDOT { - $$ = new std::vector<std::pair<PATypeHolder*,char*> >(); - $$->push_back(std::make_pair(new PATypeHolder(Type::VoidTy), (char*)0)); + $$ = new std::vector<std::pair<TypeInfo,char*> >(); + TypeInfo TI; + TI.type = new PATypeHolder(Type::VoidTy); + TI.signedness = isSignless; + $$->push_back(std::make_pair(TI, (char*)0)); CHECK_FOR_ERROR } | /* empty */ { @@ -2022,22 +2074,23 @@ FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' std::string FunctionName($3); free($3); // Free strdup'd memory! - if (!(*$2)->isFirstClassType() && *$2 != Type::VoidTy) + if (!($2.type->get())->isFirstClassType() && $2.type->get() != Type::VoidTy) GEN_ERROR("LLVM functions cannot return aggregate types!"); std::vector<const Type*> ParamTypeList; if ($5) { // If there are arguments... - for (std::vector<std::pair<PATypeHolder*,char*> >::iterator I = $5->begin(); + for (std::vector<std::pair<TypeInfo,char*> >::iterator I = $5->begin(); I != $5->end(); ++I) - ParamTypeList.push_back(I->first->get()); + ParamTypeList.push_back(I->first.type->get()); } bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; if (isVarArg) ParamTypeList.pop_back(); - const FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg); + const FunctionType *FT = FunctionType::get($2.type->get(), ParamTypeList, + isVarArg); const PointerType *PFT = PointerType::get(FT); - delete $2; + delete $2.type; ValID ID; if (!FunctionName.empty()) { @@ -2091,21 +2144,19 @@ FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' // Add all of the arguments we parsed to the function... if ($5) { // Is null if empty... if (isVarArg) { // Nuke the last entry - assert($5->back().first->get() == Type::VoidTy && $5->back().second == 0&& - "Not a varargs marker!"); - delete $5->back().first; + assert($5->back().first.type->get() == Type::VoidTy && + $5->back().second == 0 && "Not a varargs marker!"); + delete $5->back().first.type; $5->pop_back(); // Delete the last entry } Function::arg_iterator ArgIt = Fn->arg_begin(); - for (std::vector<std::pair<PATypeHolder*,char*> >::iterator I = $5->begin(); + for (std::vector<std::pair<TypeInfo,char*> >::iterator I = $5->begin(); I != $5->end(); ++I, ++ArgIt) { - delete I->first; // Delete the typeholder... - + delete I->first.type; // Delete the typeholder... setValueName(ArgIt, I->second); // Insert arg into symtab... CHECK_FOR_ERROR InsertValue(ArgIt); } - delete $5; // We're now done with the argument list } CHECK_FOR_ERROR @@ -2189,12 +2240,7 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant PackedType* pt = PackedType::get(ETy, NumElements); PATypeHolder* PTy = new PATypeHolder( - HandleUpRefs( - PackedType::get( - ETy, - NumElements) - ) - ); + HandleUpRefs(PackedType::get( ETy, NumElements))); // Verify all elements are correct type! for (unsigned i = 0; i < $2->size(); i++) { @@ -2243,7 +2289,7 @@ ValueRef : SymbolicValueRef | ConstValueRef; // type immediately preceeds the value reference, and allows complex constant // pool references (for things like: 'ret [2 x int] [ int 12, int 42]') ResolvedVal : Types ValueRef { - $$ = getVal(*$1, $2); delete $1; + $$ = getVal($1.type->get(), $2); delete $1.type; CHECK_FOR_ERROR }; @@ -2272,6 +2318,10 @@ BasicBlock : InstructionList OptAssign BBTerminatorInst { }; InstructionList : InstructionList Inst { + if (CastInst *CI1 = dyn_cast<CastInst>($2)) + if (CastInst *CI2 = dyn_cast<CastInst>(CI1->getOperand(0))) + if (CI2->getParent() == 0) + $1->getInstList().push_back(CI2); $1->getInstList().push_back($2); $$ = $1; CHECK_FOR_ERROR @@ -2324,7 +2374,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... $$ = new BranchInst(tmpBBA, tmpBBB, tmpVal); } | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' { - Value* tmpVal = getVal($2, $3); + Value* tmpVal = getVal($2.type->get(), $3); CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal($6); CHECK_FOR_ERROR @@ -2343,7 +2393,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... CHECK_FOR_ERROR } | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' { - Value* tmpVal = getVal($2, $3); + Value* tmpVal = getVal($2.type->get(), $3); CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal($6); CHECK_FOR_ERROR @@ -2356,7 +2406,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... const PointerType *PFTy; const FunctionType *Ty; - if (!(PFTy = dyn_cast<PointerType>($3->get())) || + if (!(PFTy = dyn_cast<PointerType>($3.type->get())) || !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector<const Type*> ParamTypes; @@ -2369,7 +2419,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); - Ty = FunctionType::get($3->get(), ParamTypes, isVarArg); + Ty = FunctionType::get($3.type->get(), ParamTypes, isVarArg); PFTy = PointerType::get(Ty); } @@ -2403,7 +2453,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... } cast<InvokeInst>($$)->setCallingConv($2); - delete $3; + delete $3.type; delete $6; CHECK_FOR_ERROR } @@ -2420,7 +2470,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef { $$ = $1; - Constant *V = cast<Constant>(getValNonImprovising($2, $3)); + Constant *V = cast<Constant>(getValNonImprovising($2.type->get(), $3)); CHECK_FOR_ERROR if (V == 0) GEN_ERROR("May only switch on a constant pool value!"); @@ -2431,7 +2481,7 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef { } | IntType ConstValueRef ',' LABEL ValueRef { $$ = new std::vector<std::pair<Constant*, BasicBlock*> >(); - Constant *V = cast<Constant>(getValNonImprovising($1, $2)); + Constant *V = cast<Constant>(getValNonImprovising($1.type->get(), $2)); CHECK_FOR_ERROR if (V == 0) @@ -2453,12 +2503,12 @@ Inst : OptAssign InstVal { PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes $$ = new std::list<std::pair<Value*, BasicBlock*> >(); - Value* tmpVal = getVal(*$1, $3); + Value* tmpVal = getVal($1.type->get(), $3); CHECK_FOR_ERROR BasicBlock* tmpBB = getBBVal($5); CHECK_FOR_ERROR $$->push_back(std::make_pair(tmpVal, tmpBB)); - delete $1; + delete $1.type; } | PHIList ',' '[' ValueRef ',' ValueRef ']' { $$ = $1; @@ -2493,55 +2543,55 @@ OptTailCall : TAIL CALL { }; InstVal : ArithmeticOps Types ValueRef ',' ValueRef { - if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint() && - !isa<PackedType>((*$2).get())) + if (!$2.type->get()->isInteger() && !$2.type->get()->isFloatingPoint() && + !isa<PackedType>($2.type->get())) GEN_ERROR( "Arithmetic operator requires integer, FP, or packed operands!"); - if (isa<PackedType>((*$2).get()) && + if (isa<PackedType>($2.type->get()) && ($1.opcode == Instruction::URem || $1.opcode == Instruction::SRem || $1.opcode == Instruction::FRem)) GEN_ERROR("U/S/FRem not supported on packed types!"); // Upgrade the opcode from obsolete versions before we do anything with it. - sanitizeOpCode($1,*$2); + sanitizeOpcode($1,$2.type->get()); CHECK_FOR_ERROR; - Value* val1 = getVal(*$2, $3); + Value* val1 = getVal($2.type->get(), $3); CHECK_FOR_ERROR - Value* val2 = getVal(*$2, $5); + Value* val2 = getVal($2.type->get(), $5); CHECK_FOR_ERROR $$ = BinaryOperator::create($1.opcode, val1, val2); if ($$ == 0) GEN_ERROR("binary operator returned null!"); - delete $2; + delete $2.type; } | LogicalOps Types ValueRef ',' ValueRef { - if (!(*$2)->isIntegral()) { - if (!isa<PackedType>($2->get()) || - !cast<PackedType>($2->get())->getElementType()->isIntegral()) + if (!$2.type->get()->isIntegral()) { + if (!isa<PackedType>($2.type->get()) || + !cast<PackedType>($2.type->get())->getElementType()->isIntegral()) GEN_ERROR("Logical operator requires integral operands!"); } - Value* tmpVal1 = getVal(*$2, $3); + Value* tmpVal1 = getVal($2.type->get(), $3); CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$2, $5); + Value* tmpVal2 = getVal($2.type->get(), $5); CHECK_FOR_ERROR $$ = BinaryOperator::create($1.opcode, tmpVal1, tmpVal2); if ($$ == 0) GEN_ERROR("binary operator returned null!"); - delete $2; + delete $2.type; } | SetCondOps Types ValueRef ',' ValueRef { - if(isa<PackedType>((*$2).get())) { + if(isa<PackedType>($2.type->get())) { GEN_ERROR( "PackedTypes currently not supported in setcc instructions!"); } - Value* tmpVal1 = getVal(*$2, $3); + Value* tmpVal1 = getVal($2.type->get(), $3); CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$2, $5); + Value* tmpVal2 = getVal($2.type->get(), $5); CHECK_FOR_ERROR $$ = new SetCondInst($1.opcode, tmpVal1, tmpVal2); if ($$ == 0) GEN_ERROR("binary operator returned null!"); - delete $2; + delete $2.type; } | NOT ResolvedVal { std::cerr << "WARNING: Use of eliminated 'not' instruction:" @@ -2562,18 +2612,36 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { if (!$2->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); // Handle opcode upgrade situations - sanitizeOpCode($1, $2->getType()); + sanitizeOpcode($1, $2->getType()); CHECK_FOR_ERROR; $$ = new ShiftInst($1.opcode, $2, $4); CHECK_FOR_ERROR } - | CAST ResolvedVal TO Types { - if (!$4->get()->isFirstClassType()) - GEN_ERROR("cast instruction to a non-primitive type: '" + - $4->get()->getDescription() + "'!"); - $$ = new CastInst($2, *$4); - delete $4; - CHECK_FOR_ERROR + | CastOps ResolvedVal TO Types { + Value* Val = $2; + const Type* Ty = $4.type->get(); + if (!Val->getType()->isFirstClassType()) + GEN_ERROR("cast from a non-primitive type: '" + + Val->getType()->getDescription() + "'!"); + if (!Ty->isFirstClassType()) + GEN_ERROR("cast to a non-primitive type: '" + Ty->getDescription() +"'!"); + + if ($1.obsolete) { + if (Ty == Type::BoolTy) { + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + $$ = new SetCondInst(Instruction::SetNE, $2, + Constant::getNullValue($2->getType())); + } else if (Val->getType()->isFloatingPoint() && isa<PointerType>(Ty)) { + CastInst *CI = new FPToUIInst(Val, Type::ULongTy); + $$ = new IntToPtrInst(CI, Ty); + } else { + $$ = CastInst::createInferredCast(Val, Ty); + } + } else { + $$ = CastInst::create($1.opcode, $2, $4.type->get()); + } + delete $4.type; } | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { if ($2->getType() != Type::BoolTy) @@ -2585,8 +2653,8 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { } | VAARG ResolvedVal ',' Types { NewVarArgs = true; - $$ = new VAArgInst($2, *$4); - delete $4; + $$ = new VAArgInst($2, $4.type->get()); + delete $4.type; CHECK_FOR_ERROR } | VAARG_old ResolvedVal ',' Types { @@ -2605,8 +2673,8 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { CallInst* bar = new CallInst(NF, $2); CurBB->getInstList().push_back(bar); CurBB->getInstList().push_back(new StoreInst(bar, foo)); - $$ = new VAArgInst(foo, *$4); - delete $4; + $$ = new VAArgInst(foo, $4.type->get()); + delete $4.type; CHECK_FOR_ERROR } | VANEXT_old ResolvedVal ',' Types { @@ -2626,10 +2694,10 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { CallInst* bar = new CallInst(NF, $2); CurBB->getInstList().push_back(bar); CurBB->getInstList().push_back(new StoreInst(bar, foo)); - Instruction* tmp = new VAArgInst(foo, *$4); + Instruction* tmp = new VAArgInst(foo, $4.type->get()); CurBB->getInstList().push_back(tmp); $$ = new LoadInst(foo); - delete $4; + delete $4.type; CHECK_FOR_ERROR } | EXTRACTELEMENT ResolvedVal ',' ResolvedVal { @@ -2666,10 +2734,10 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { CHECK_FOR_ERROR } | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' { - const PointerType *PFTy; - const FunctionType *Ty; + const PointerType *PFTy = 0; + const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast<PointerType>($3->get())) || + if (!(PFTy = dyn_cast<PointerType>($3.type->get())) || !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector<const Type*> ParamTypes; @@ -2682,10 +2750,11 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); - if (!(*$3)->isFirstClassType() && *$3 != Type::VoidTy) + if (!$3.type->get()->isFirstClassType() && + $3.type->get() != Type::VoidTy) GEN_ERROR("LLVM functions cannot return aggregate types!"); - Ty = FunctionType::get($3->get(), ParamTypes, isVarArg); + Ty = FunctionType::get($3.type->get(), ParamTypes, isVarArg); PFTy = PointerType::get(Ty); } @@ -2720,7 +2789,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { } cast<CallInst>($$)->setTailCall($1); cast<CallInst>($$)->setCallingConv($2); - delete $3; + delete $3.type; delete $6; CHECK_FOR_ERROR } @@ -2751,26 +2820,26 @@ OptVolatile : VOLATILE { MemoryInst : MALLOC Types OptCAlign { - $$ = new MallocInst(*$2, 0, $3); - delete $2; + $$ = new MallocInst($2.type->get(), 0, $3); + delete $2.type; CHECK_FOR_ERROR } | MALLOC Types ',' UINT ValueRef OptCAlign { - Value* tmpVal = getVal($4, $5); + Value* tmpVal = getVal($4.type->get(), $5); CHECK_FOR_ERROR - $$ = new MallocInst(*$2, tmpVal, $6); - delete $2; + $$ = new MallocInst($2.type->get(), tmpVal, $6); + delete $2.type; } | ALLOCA Types OptCAlign { - $$ = new AllocaInst(*$2, 0, $3); - delete $2; + $$ = new AllocaInst($2.type->get(), 0, $3); + delete $2.type; CHECK_FOR_ERROR } | ALLOCA Types ',' UINT ValueRef OptCAlign { - Value* tmpVal = getVal($4, $5); + Value* tmpVal = getVal($4.type->get(), $5); CHECK_FOR_ERROR - $$ = new AllocaInst(*$2, tmpVal, $6); - delete $2; + $$ = new AllocaInst($2.type->get(), tmpVal, $6); + delete $2.type; } | FREE ResolvedVal { if (!isa<PointerType>($2->getType())) @@ -2781,54 +2850,54 @@ MemoryInst : MALLOC Types OptCAlign { } | OptVolatile LOAD Types ValueRef { - if (!isa<PointerType>($3->get())) + if (!isa<PointerType>($3.type->get())) GEN_ERROR("Can't load from nonpointer type: " + - (*$3)->getDescription()); - if (!cast<PointerType>($3->get())->getElementType()->isFirstClassType()) + $3.type->get()->getDescription()); + if (!cast<PointerType>($3.type->get())->getElementType()->isFirstClassType()) GEN_ERROR("Can't load from pointer of non-first-class type: " + - (*$3)->getDescription()); - Value* tmpVal = getVal(*$3, $4); + $3.type->get()->getDescription()); + Value* tmpVal = getVal($3.type->get(), $4); CHECK_FOR_ERROR $$ = new LoadInst(tmpVal, "", $1); - delete $3; + delete $3.type; } | OptVolatile STORE ResolvedVal ',' Types ValueRef { - const PointerType *PT = dyn_cast<PointerType>($5->get()); + const PointerType *PT = dyn_cast<PointerType>($5.type->get()); if (!PT) GEN_ERROR("Can't store to a nonpointer type: " + - (*$5)->getDescription()); + ($5.type->get())->getDescription()); const Type *ElTy = PT->getElementType(); if (ElTy != $3->getType()) GEN_ERROR("Can't store '" + $3->getType()->getDescription() + "' into space of type '" + ElTy->getDescription() + "'!"); - Value* tmpVal = getVal(*$5, $6); + Value* tmpVal = getVal($5.type->get(), $6); CHECK_FOR_ERROR $$ = new StoreInst($3, tmpVal, $1); - delete $5; + delete $5.type; } | GETELEMENTPTR Types ValueRef IndexList { - if (!isa<PointerType>($2->get())) + if (!isa<PointerType>($2.type->get())) GEN_ERROR("getelementptr insn requires pointer operand!"); // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte struct // indices to uint struct indices for compatibility. generic_gep_type_iterator<std::vector<Value*>::iterator> - GTI = gep_type_begin($2->get(), $4->begin(), $4->end()), - GTE = gep_type_end($2->get(), $4->begin(), $4->end()); + GTI = gep_type_begin($2.type->get(), $4->begin(), $4->end()), + GTE = gep_type_end($2.type->get(), $4->begin(), $4->end()); for (unsigned i = 0, e = $4->size(); i != e && GTI != GTE; ++i, ++GTI) if (isa<StructType>(*GTI)) // Only change struct indices if (ConstantInt *CUI = dyn_cast<ConstantInt>((*$4)[i])) if (CUI->getType() == Type::UByteTy) (*$4)[i] = ConstantExpr::getCast(CUI, Type::UIntTy); - if (!GetElementPtrInst::getIndexedType(*$2, *$4, true)) + if (!GetElementPtrInst::getIndexedType($2.type->get(), *$4, true)) GEN_ERROR("Invalid getelementptr indices for type '" + - (*$2)->getDescription()+ "'!"); - Value* tmpVal = getVal(*$2, $3); + $2.type->get()->getDescription()+ "'!"); + Value* tmpVal = getVal($2.type->get(), $3); CHECK_FOR_ERROR $$ = new GetElementPtrInst(tmpVal, *$4); - delete $2; + delete $2.type; delete $4; }; diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 86e011eb0a..9a501f183a 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -461,24 +461,23 @@ void BytecodeReader::insertArguments(Function* F) { insertValue(AI, getTypeSlot(AI->getType()), FunctionValues); } -// Convert previous opcode values into the current value and/or construct -// the instruction. This function handles all *abnormal* cases for instruction -// generation based on obsolete opcode values. The normal cases are handled -// in ParseInstruction below. Generally this function just produces a new -// Opcode value (first argument). In a few cases (VAArg, VANext) the upgrade -// path requies that the instruction (sequence) be generated differently from -// the normal case in order to preserve the original semantics. In these -// cases the result of the function will be a non-zero Instruction pointer. In -// all other cases, zero will be returned indicating that the *normal* -// instruction generation should be used, but with the new Opcode value. -// +/// Convert previous opcode values into the current value and/or construct +/// the instruction. This function handles all *abnormal* cases for instruction +/// generation based on obsolete opcode values. The normal cases are handled +/// in ParseInstruction below. Generally this function just produces a new +/// Opcode value (first argument). In a few cases (VAArg, VANext) the upgrade +/// path requies that the instruction (sequence) be generated differently from +/// the normal case in order to preserve the original semantics. In these +/// cases the result of the function will be a non-zero Instruction pointer. In +/// all other cases, zero will be returned indicating that the *normal* +/// instruction generation should be used, but with the new Opcode value. Instruction* BytecodeReader::upgradeInstrOpcodes( unsigned &Opcode, ///< The old opcode, possibly updated by this function std::vector<unsigned> &Oprnds, ///< The operands to the instruction unsigned &iType, ///< The type code from the bytecode file - const Type* InstTy, ///< The type of the instruction - BasicBlock* BB ///< The basic block to insert into, if we need to + const Type *InstTy, ///< The type of the instruction + BasicBlock *BB ///< The basic block to insert into, if we need to ) { // First, short circuit this if no conversion is required. When signless @@ -632,8 +631,27 @@ BytecodeReader::upgradeInstrOpcodes( Opcode = Instruction::PHI; break; case 28: // Cast - Opcode = Instruction::Cast; + { + Value *Source = getValue(iType, Oprnds[0]); + const Type *DestTy = getType(Oprnds[1]); + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + if (DestTy == Type::BoolTy) { // if its a cast to bool + Opcode = Instruction::SetNE; + Result = new SetCondInst(Instruction::SetNE, Source, + Constant::getNullValue(Source->getType())); + } else if (Source->getType()->isFloatingPoint() && + isa<PointerType>(DestTy)) { + // Upgrade what is now an illegal cast (fp -> ptr) into two casts, + // fp -> ui, and ui -> ptr + CastInst *CI = new FPToUIInst(Source, Type::ULongTy); + BB->getInstList().push_back(CI); + Result = new IntToPtrInst(CI, DestTy); + } else { + Result = CastInst::createInferredCast(Source, DestTy); + } break; + } case 29: // Call Opcode = Instruction::Call; break; @@ -720,8 +738,66 @@ BytecodeReader::upgradeInstrOpcodes( case 40: // ShuffleVector Opcode = Instruction::ShuffleVector; break; - case 56: // Invoke with encoded CC - case 57: // Invoke Fast CC + case 56: // Invoke with encoded CC + case 57: { // Invoke Fast CC + if (Oprnds.size() < 3) + error("Invalid invoke instruction!"); + Value *F = getValue(iType, Oprnds[0]); + + // Check to make sure we have a pointer to function type + const PointerType *PTy = dyn_cast<PointerType>(F->getType()); + if (PTy == 0) + error("Invoke to non function pointer value!"); + const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType()); + if (FTy == 0) + error("Invoke to non function pointer value!"); + + std::vector<Value *> Params; + BasicBlock *Normal, *Except; + unsigned CallingConv = CallingConv::C; + if (Opcode == 57) + CallingConv = CallingConv::Fast; + else if (Opcode == 56) { + CallingConv = Oprnds.back(); + Oprnds.pop_back(); + } + Opcode = Instruction::Invoke; + + if (!FTy->isVarArg()) { + Normal = getBasicBlock(Oprnds[1]); + Except = getBasicBlock(Oprnds[2]); + + FunctionType::param_iterator It = FTy->param_begin(); + for (unsigned i = 3, e = Oprnds.size(); i != e; ++i) { + if (It == FTy->param_end()) + error("Invalid invoke instruction!"); + Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i])); + } + if (It != FTy->param_end()) + error("Invalid invoke instruction!"); + } else { + Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1); + + Normal = getBasicBlock(Oprnds[0]); + Except = getBasicBlock(Oprnds[1]); + + unsigned FirstVariableArgument = FTy->getNumParams()+2; + for (unsigned i = 2; i != FirstVariableArgument; ++i) + Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)), + Oprnds[i])); + + // Must be type/value pairs. If not, error out. + if (Oprnds.size()-FirstVariableArgument & 1) + error("Invalid invoke instruction!"); + + for (unsigned i = FirstVariableArgument; i < Oprnds.size(); i += 2) + Params.push_back(getValue(Oprnds[i], Oprnds[i+1])); + } + + Result = new InvokeInst(F, Normal, Except, Params); + if (CallingConv) cast<InvokeInst>(Result)->setCallingConv(CallingConv); + break; + } case 58: // Call with extra operand for calling conv case 59: // tail call, Fast CC case 60: // normal call, Fast CC @@ -889,12 +965,78 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds, Result = new ShuffleVectorInst(V1, V2, V3); break; } - case Instruction::Cast: + case Instruction::Trunc: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new TruncInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::ZExt: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new ZExtInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::SExt: if (Oprnds.size() != 2) error("Invalid Cast instruction!"); - Result = new CastInst(getValue(iType, Oprnds[0]), + Result = new SExtInst(getValue(iType, Oprnds[0]), getType(Oprnds[1])); break; + case Instruction::FPTrunc: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new FPTruncInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::FPExt: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new FPExtInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::UIToFP: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new UIToFPInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::SIToFP: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new SIToFPInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::FPToUI: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new FPToUIInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::FPToSI: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new FPToSIInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::IntToPtr: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new IntToPtrInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::PtrToInt: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new PtrToIntInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; + case Instruction::BitCast: + if (Oprnds.size() != 2) + error("Invalid cast instruction!"); + Result = new BitCastInst(getValue(iType, Oprnds[0]), + getType(Oprnds[1])); + break; case Instruction::Select: if (Oprnds.size() != 3) error("Invalid Select instruction!"); @@ -914,7 +1056,6 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds, Result = PN; break; } - case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: @@ -960,7 +1101,6 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds, case Instruction::Call: { // Normal Call, C Calling Convention if (Oprnds.size() == 0) error("Invalid call instruction encountered!"); - Value *F = getValue(iType, Oprnds[0]); unsigned CallingConv = CallingConv::C; @@ -1021,8 +1161,6 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds, if (CallingConv) cast<CallInst>(Result)->setCallingConv(CallingConv); break; } - case 56: // Invoke with encoded CC - case 57: // Invoke Fast CC case Instruction::Invoke: { // Invoke C CC if (Oprnds.size() < 3) error("Invalid invoke instruction!"); @@ -1038,14 +1176,8 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds, std::vector<Value *> Params; BasicBlock *Normal, *Except; - unsigned CallingConv = CallingConv::C; - - if (Opcode == 57) - CallingConv = CallingConv::Fast; - else if (Opcode == 56) { - CallingConv = Oprnds.back(); - Oprnds.pop_back(); - } + unsigned CallingConv = Oprnds.back(); + Oprnds.pop_back(); if (!FTy->isVarArg()) { Normal = getBasicBlock(Oprnds[1]); @@ -1486,12 +1618,12 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){ // We can't use that function because of that functions argument requirements. // This function only deals with the subset of opcodes that are applicable to // constant expressions and is therefore simpler than upgradeInstrOpcodes. -inline unsigned BytecodeReader::upgradeCEOpcodes( - unsigned Opcode, const std::vector<Constant*> &ArgVec +inline Constant *BytecodeReader::upgradeCEOpcodes( + unsigned &Opcode, const std::vector<Constant*> &ArgVec, unsigned TypeID ) { // Determine if no upgrade necessary if (!hasSignlessDivRem && !hasSignlessShrCastSetcc) - return Opcode; + return 0; // If this is bytecode version 6, that only had signed Rem and Div // instructions, then we must compensate for those two instructions only. @@ -1587,9 +1719,25 @@ inline unsigned BytecodeReader::upgradeCEOpcodes( case 26: // GetElementPtr Opcode = Instruction::GetElementPtr; break; - case 28: // Cast - Opcode = Instruction::Cast; + case 28: { // Cast + const Type *Ty = getType(TypeID); + if (Ty == Type::BoolTy) { + // The previous definition of cast to bool was a compare against zero. + // We have to retain that semantic so we do it here. + Opcode = Instruction::SetEQ; + return ConstantExpr::get(Instruction::SetEQ, ArgVec[0], + Constant::getNullValue(ArgVec[0]->getType())); + } else if (ArgVec[0]->getType()->isFloatingPoint() && + isa<PointerType>(Ty)) { + // Upgrade what is now an illegal cast (fp -> ptr) into two casts, + // fp -> ui, and ui -> ptr + Constant *CE = ConstantExpr::getFPToUI(ArgVec[0], Type::ULongTy); + return ConstantExpr::getIntToPtr(CE, Ty); + } else { + Opcode = CastInst::getCastOpcode(ArgVec[0], Ty); + } break; + } case 30: // Shl Opcode = Instruction::Shl; break; @@ -1612,7 +1760,7 @@ inline unsigned BytecodeReader::upgradeCEOpcodes( Opcode = Instruction::ShuffleVector; break; } - return Opcode; + return 0; } /// Parse a single constant value @@ -1663,19 +1811,22 @@ Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) { } // Handle backwards compatibility for the opcode numbers - Opcode = upgradeCEOpcodes(Opcode, ArgVec); + if (Constant *C = upgradeCEOpcodes(Opcode, ArgVec, TypeID)) { + if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, C); + return C; + } // Construct a ConstantExpr of the appropriate kind if (isExprNumArgs == 1) { // All one-operand expressions - if (Opcode != Instruction::Cast) + if (!Instruction::isCast(Opcode)) error("Only cast instruction has one argument for ConstantExpr"); - Constant* Result = ConstantExpr::getCast(ArgVec[0], getType(TypeID)); + Constant *Result = ConstantExpr::getCast(ArgVec[0], getType(TypeID)); if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result); return Result; } else if (Opcode == Instruction::GetElementPtr) { // GetElementPtr std::vector<Constant*> IdxList(ArgVec.begin()+1, ArgVec.end()); - Constant* Result = ConstantExpr::getGetElementPtr(ArgVec[0], IdxList); + Constant *Result = ConstantExpr::getGetElementPtr(ArgVec[0], IdxList); if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result); return Result; } else if (Opcode == Instruction::Select) { diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h index 37c4324c3e..3ede6eb034 100644 --- a/lib/Bytecode/Reader/Reader.h +++ b/lib/Bytecode/Reader/Reader.h @@ -230,19 +230,20 @@ protected: /// the instruction. This function handles all *abnormal* cases for /// instruction generation based on obsolete opcode values. The normal cases /// are handled by the ParseInstruction function. - Instruction* upgradeInstrOpcodes( + Instruction *upgradeInstrOpcodes( unsigned &opcode, ///< The old opcode, possibly updated by this function std::vector<unsigned> &Oprnds, ///< The operands to the instruction unsigned &iType, ///< The type code from the bytecode file - const Type* InstTy, ///< The type of the instruction - BasicBlock* BB ///< The basic block to insert into, if we need to + const Type *InstTy, ///< The type of the instruction + BasicBlock *BB ///< The basic block to insert into, if we need to ); /// @brief Convert previous opcode values for ConstantExpr into the current /// value. - unsigned upgradeCEOpcodes( - unsigned Opcode, ///< Opcode read from bytecode - const std::vector<Constant*> &ArgVec ///< Arguments of instruction + Constant *upgradeCEOpcodes( + unsigned &Opcode, ///< Opcode read from bytecode + const std::vector<Constant*> &ArgVec, ///< Arguments of instruction + unsigned TypeID ///< TypeID of the instruction type ); /// @brief Parse a single instruction. diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index dbc789652a..f2ded65b07 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -291,7 +291,7 @@ void BytecodeWriter::outputConstant(const Constant *CPV) { if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) { // FIXME: Encoding of constant exprs could be much more compact! assert(CE->getNumOperands() > 0 && "ConstantExpr with 0 operands"); - assert(CE->getNumOperands() != 1 || CE->getOpcode() == Instruction::Cast); + assert(CE->getNumOperands() != 1 || CE->isCast()); output_vbr(1+CE->getNumOperands()); // flags as an expr output_vbr(CE->getOpcode()); // Put out the CE op code @@ -446,8 +446,8 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, output_typeid(Type); // Result type unsigned NumArgs = I->getNumOperands(); - output_vbr(NumArgs + (isa<CastInst>(I) || - isa<VAArgInst>(I) || Opcode == 56 || Opcode == 58)); + output_vbr(NumArgs + (isa<CastInst>(I) || isa<InvokeInst>(I) || + isa<VAArgInst>(I) || Opcode == 58)); if (!isa<GetElementPtrInst>(&I)) { for (unsigned i = 0; i < NumArgs; ++i) { @@ -460,7 +460,7 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I, int Slot = Table.getSlot(I->getType()); assert(Slot != -1 && "Cast return type unknown?"); output_typeid((unsigned)Slot); - } else if (Opcode == 56) { // Invoke escape sequence + } else if (isa<InvokeInst>(I)) { output_vbr(cast<InvokeInst>(I)->getCallingConv()); } else if (Opcode == 58) { // Call escape sequence output_vbr((cast<CallInst>(I)->getCallingConv() << 1) | @@ -528,8 +528,8 @@ void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I, // variable argument. NumFixedOperands = 3+NumParams; } - output_vbr(2 * I->getNumOperands()-NumFixedOperands + - unsigned(Opcode == 56 || Opcode == 58)); + output_vbr(2 * I->getNumOperands()-NumFixedOperands + + unsigned(Opcode == 58 || isa<InvokeInst>(I))); // The type for the function has already been emitted in the type field of the // instruction. Just emit the slot # now. @@ -551,12 +551,12 @@ void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I, output_vbr((unsigned)Slot); } - // If this is the escape sequence for call, emit the tailcall/cc info. - if (Opcode == 58) { + if (isa<InvokeInst>(I)) { + // Emit the tail call/calling conv for invoke instructions + output_vbr(cast<InvokeInst>(I)->getCallingConv()); + } else if (Opcode == 58) { const CallInst *CI = cast<CallInst>(I); output_vbr((CI->getCallingConv() << 1) | unsigned(CI->isTailCall())); - } else if (Opcode == 56) { // Invoke escape sequence. - output_vbr(cast<InvokeInst>(I)->getCallingConv()); } } @@ -619,7 +619,7 @@ inline void BytecodeWriter::outputInstructionFormat3(const Instruction *I, } void BytecodeWriter::outputInstruction(const Instruction &I) { - assert(I.getOpcode() < 56 && "Opcode too big???"); + assert(I.getOpcode() < 57 && "Opcode too big???"); unsigned Opcode = I.getOpcode(); unsigned NumOperands = I.getNumOperands(); @@ -639,12 +639,6 @@ void BytecodeWriter::outputInstruction(const Instruction &I) { } else { Opcode = 58; // Call escape sequence. } - } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { - if (II->getCallingConv() == CallingConv::Fast) - Opcode = 57; // FastCC invoke. - else if (II->getCallingConv() != CallingConv::C) - Opcode = 56; // Invoke escape sequence. - } else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) { Opcode = 62; } else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) { @@ -750,7 +744,7 @@ void BytecodeWriter::outputInstruction(const Instruction &I) { if (Slots[NumOperands-1] > MaxOpSlot) MaxOpSlot = Slots[NumOperands-1]; } - } else if (Opcode == 56) { + } else if (isa<InvokeInst>(I)) { // Invoke escape seq has at least 4 operands to encode. ++NumOperands; } diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index c2f5d7334c..ac8d324363 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -423,7 +423,20 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { } break; } - case Instruction::Cast: { + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + assert(0 && "FIXME: Don't yet support this kind of constant cast expr"); + break; + case Instruction::IntToPtr: + case Instruction::PtrToInt: + case Instruction::BitCast: { // Support only foldable casts to/from pointers that can be eliminated by // changing the pointer to the appropriately sized integer type. Constant *Op = CE->getOperand(0); diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index ece3072d00..2df839ff39 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -40,6 +40,7 @@ static Function *EnsureFunctionExists(Module &M, const char *Name, template <class ArgIt> static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, ArgIt ArgBegin, ArgIt ArgEnd, + const unsigned *castOpcodes, const Type *RetTy, Function *&FCache) { if (!FCache) { // If we haven't already looked up this function, check to see if the @@ -63,7 +64,12 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, ++I, ++ArgNo) { Value *Arg = *I; if (Arg->getType() != FT->getParamType(ArgNo)) - Arg = new CastInst(Arg, FT->getParamType(ArgNo), Arg->getName(), CI); + if (castOpcodes[ArgNo]) + Arg = CastInst::create(Instruction::CastOps(castOpcodes[ArgNo]), + Arg, FT->getParamType(ArgNo), Arg->getName(), CI); + else + Arg = CastInst::createInferredCast(Arg, FT->getParamType(ArgNo), + Arg->getName(), CI); Operands.push_back(Arg); } // Pass nulls into any additional arguments... @@ -76,7 +82,7 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, if (!CI->use_empty()) { Value *V = NewCI; if (CI->getType() != NewCI->getType()) - V = new CastInst(NewCI, CI->getType(), Name, CI); + V = CastInst::createInferredCast(NewCI, CI->getType(), Name, CI); CI->replaceAllUsesWith(V); } return NewCI; @@ -283,8 +289,9 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { // convert the call to an explicit setjmp or longjmp call. case Intrinsic::setjmp: { static Function *SetjmpFCache = 0; + static const unsigned castOpcodes[] = { Instruction::BitCast }; Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin()+1, CI->op_end(), - Type::IntTy, SetjmpFCache); + castOpcodes, Type::IntTy, SetjmpFCache); if (CI->getType() != Type::VoidTy) CI->replaceAllUsesWith(V); break; @@ -296,16 +303,20 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { case Intrinsic::longjmp: { static Function *LongjmpFCache = 0; + static const unsigned castOpcodes[] = + { Instruction::BitCast, 0 }; ReplaceCallWith("longjmp", CI, CI->op_begin()+1, CI->op_end(), - Type::VoidTy, LongjmpFCache); + castOpcodes, Type::VoidTy, LongjmpFCache); break; } case Intrinsic::siglongjmp: { // Insert the call to abort static Function *AbortFCache = 0; - ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), Type::VoidTy, - AbortFCache); + static const unsigned castOpcodes[] = + { Instruction::BitCast, 0 }; + ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), + castOpcodes, Type::VoidTy, AbortFCache); break; } case Intrinsic::ctpop_i8: @@ -383,31 +394,76 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { case Intrinsic::dbg_declare: break; // Simply strip out debugging intrinsics - case Intrinsic::memcpy_i32: - case Intrinsic::memcpy_i64: { + case Intrinsic::memcpy_i32: { // The memcpy intrinsic take an extra alignment argument that the memcpy // libc function does not. + static unsigned opcodes[] = + { Instruction::BitCast, Instruction::BitCast, Instruction::BitCast }; + // FIXME: + // if (target_is_64_bit) opcodes[2] = Instruction::ZExt; + // else opcodes[2] = Instruction::BitCast; + static Function *MemcpyFCache = 0; + ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1, + opcodes, (*(CI->op_begin()+1))->getType(), MemcpyFCache); + break; + } + case Intrinsic::memcpy_i64: { + static unsigned opcodes[] = + { Instruction::BitCast, Instruction::BitCast, Instruction::Trunc }; + // FIXME: + // if (target_is_64_bit) opcodes[2] = Instruction::BitCast; + // else opcodes[2] = Instruction::Trunc; static Function *MemcpyFCache = 0; ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1, - (*(CI->op_begin()+1))->getType(), MemcpyFCache); + opcodes, (*(CI->op_begin()+1))->getType(), MemcpyFCache); + break; + } + case Intrinsic::memmove_i32: { + // The memmove intrinsic take an extra alignment argument that the memmove + // libc function does not. + static unsigned opcodes[] = + { Instruction::BitCast, Instruction::BitCast, Instruction::BitCast }; + // FIXME: + // if (target_is_64_bit) opcodes[2] = Instruction::ZExt; + // else opcodes[2] = Instruction::BitCast; + static Function *MemmoveFCache = 0; + ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1, + opcodes, (*(CI->op_begin()+1))->getType(), MemmoveFCache); break; } - case Intrinsic::memmove_i32: case Intrinsic::memmove_i64: { // The memmove intrinsic take an extra alignment argument that the memmove // libc function does not. + static const unsigned opcodes[] = + { Instruction::BitCast, Instruction::BitCast, Instruction::Trunc }; + // if (target_is_64_bit) opcodes[2] = Instruction::BitCast; + // else opcodes[2] = Instruction::Trunc; static Function *MemmoveFCache = 0; ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1, - (*(CI->op_begin()+1))->getType(), MemmoveFCache); + opcodes, (*(CI->op_begin()+1))->getType(), MemmoveFCache); break; } - case Intrinsic::memset_i32: + case Intrinsic::memset_i32: { + // The memset intrinsic take an extra alignment argument that the memset + // libc function does not. + static const unsigned opcodes[] = + { Instruction::BitCast, Instruction::ZExt, Instruction::ZExt, 0 }; + // if (target_is_64_bit) opcodes[2] = Instruction::BitCast; + // else opcodes[2] = Instruction::ZExt; + static Function *MemsetFCache = 0; + ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1, + opcodes, (*(CI->op_begin()+1))->getType(), MemsetFCache); + } case Intrinsic::memset_i64: { // The memset intrinsic take an extra alignment argument that the memset // libc function does not. + static const unsigned opcodes[] = + { Instruction::BitCast, Instruction::ZExt, Instruction::Trunc, 0 }; + // if (target_is_64_bit) opcodes[2] = Instruction::BitCast; + // else opcodes[2] = Instruction::Trunc; static Function *MemsetFCache = 0; ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1, - (*(CI->op_begin()+1))->getType(), MemsetFCache); + opcodes, (*(CI->op_begin()+1))->getType(), MemsetFCache); break; } case Intrinsic::isunordered_f32: @@ -422,16 +478,18 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { "isunordered", CI)); break; } - case Intrinsic::sqrt_f32: + case Intrinsic::sqrt_f32: { + static const unsigned opcodes[] = { 0 }; + static Function *sqrtfFCache = 0; + ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(), + opcodes, Type::FloatTy, sqrtfFCache); + break; + } case Intrinsic::sqrt_f64: { + static const unsigned opcodes[] = { 0 }; static Function *sqrtFCache = 0; - static Function *sqrtfFCache = 0; - if(CI->getType() == Type::FloatTy) - ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(), - Type::FloatTy, sqrtfFCache); - else - ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(), - Type::DoubleTy, sqrtFCache); + ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(), + opcodes, Type::DoubleTy, sqrtFCache); break; } } diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp index bdbdd144fd..16f8dc8e20 100644 --- a/lib/CodeGen/MachineDebugInfo.cpp +++ b/lib/CodeGen/MachineDebugInfo.cpp @@ -102,7 +102,7 @@ static GlobalVariable *getGlobalVariable(Value *V) { if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { return GV; } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::Cast) { + if (CE->getOpcode() == Instruction::BitCast) { return dyn_cast<GlobalVariable>(CE->getOperand(0)); } } @@ -115,7 +115,7 @@ static bool isGlobalVariable(Value *V) { if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) { return true; } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::Cast) { + if (CE->getOpcode() == Instruction::BitCast) { return isa<GlobalVariable>(CE->getOperand(0)); } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 8b9fa86329..c18b5bc274 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -557,13 +557,25 @@ public: ISD::SETOLT); } void visitSetGT(User &I) { visitSetCC(I, ISD::SETGT, ISD::SETUGT, ISD::SETOGT); } + // Visit the conversion instructions + void visitTrunc(User &I); + void visitZExt(User &I); + void visitSExt(User &I); + void visitFPTrunc(User &I); + void visitFPExt(User &I); + void visitFPToUI(User &I); + void visitFPToSI(User &I); + void visitUIToFP(User &I); + void visitSIToFP(User &I); + void visitPtrToInt(User &I); + void visitIntToPtr(User &I); + void visitBitCast(User &I); void visitExtractElement(User &I); void visitInsertElement(User &I); void visitShuffleVector(User &I); void visitGetElementPtr(User &I); - void visitCast(User &I); void visitSelect(User &I); void visitMalloc(MallocInst &I); @@ -1525,63 +1537,127 @@ void SelectionDAGLowering::visitSelect(User &I) { } } -void SelectionDAGLowering::visitCast(User &I) { + +void SelectionDAGLowering::visitTrunc(User &I) { + // TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest). + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N)); +} + +void SelectionDAGLowering::visitZExt(User &I) { + // ZExt cannot be a no-op cast because sizeof(src) < sizeof(dest). + // ZExt also can't be a cast to bool for same reason. So, nothing much to do + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N)); +} + +void SelectionDAGLowering::visitSExt(User &I) { + // SExt cannot be a no-op cast because sizeof(src) < sizeof(dest). + // SExt also can't be a cast to bool for same reason. So, nothing much to do + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DestVT, N)); +} + +void SelectionDAGLowering::visitFPTrunc(User &I) { + // FPTrunc is never a no-op cast, no need to check + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N)); +} + +void SelectionDAGLowering::visitFPExt(User &I){ + // FPTrunc is never a no-op cast, no need to check + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_EXTEND, DestVT, N)); +} + +void SelectionDAGLowering::visitFPToUI(User &I) { + // FPToUI is never a no-op cast, no need to check + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DestVT, N)); +} + +void SelectionDAGLowering::visitFPToSI(User &I) { + // FPToSI is never a no-op cast, no need to check + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DestVT, N)); +} + +void SelectionDAGLowering::visitUIToFP(User &I) { + // UIToFP is never a no-op cast, no need to check + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DestVT, N)); +} + +void SelectionDAGLowering::visitSIToFP(User &I){ + // UIToFP is never a no-op cast, no need to check + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N)); +} + +void SelectionDAGLowering::visitPtrToInt(User &I) { + // What to do depends on the size of the integer and the size of the pointer. + // We can either truncate, zero extend, or no-op, accordingly. SDOperand N = getValue(I.getOperand(0)); MVT::ValueType SrcVT = N.getValueType(); MVT::ValueType DestVT = TLI.getValueType(I.getType()); + SDOperand Result; + if (MVT::getSizeInBits(DestVT) < MVT::getSizeInBits(SrcVT)) + Result = DAG.getNode(ISD::TRUNCATE, DestVT, N); + else + // Note: ZERO_EXTEND can handle cases where the sizes are equal too + Result = DAG.getNode(ISD::ZERO_EXTEND, DestVT, N); + setValue(&I, Result); +} +void SelectionDAGLowering::visitIntToPtr(User &I) { + // What to do depends on the size of the integer and the size of the pointer. + // We can either truncate, zero extend, or no-op, accordingly. + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType SrcVT = N.getValueType(); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); + if (MVT::getSizeInBits(DestVT) < MVT::getSizeInBits(SrcVT)) + setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N)); + else + // Note: ZERO_EXTEND can handle cases where the sizes are equal too + setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N)); +} + +void SelectionDAGLowering::visitBitCast(User &I) { + SDOperand N = getValue(I.getOperand(0)); + MVT::ValueType DestVT = TLI.getValueType(I.getType()); if (DestVT == MVT::Vector) { - // This is a cast to a vector from something else. This is always a bit - // convert. Get information about the input vector. + // This is a cast to a vector from something else. + // Get information about the output vector. const PackedType *DestTy = cast<PackedType>(I.getType()); MVT::ValueType EltVT = TLI.getValueType(DestTy->getElementType()); setValue(&I, DAG.getNode(ISD::VBIT_CONVERT, DestVT, N, DAG.getConstant(DestTy->getNumElements(),MVT::i32), DAG.getValueType(EltVT))); - } else if (SrcVT == DestVT) { - setValue(&I, N); // noop cast. - } else if (DestVT == MVT::i1) { - // Cast to bool is a comparison against zero, not truncation to zero. - SDOperand Zero = isInteger(SrcVT) ? DAG.getConstant(0, N.getValueType()) : - DAG.getConstantFP(0.0, N.getValueType()); - setValue(&I, DAG.getSetCC(MVT::i1, N, Zero, ISD::SETNE)); - } else if (isInteger(SrcVT)) { - if (isInteger(DestVT)) { // Int -> Int cast - if (DestVT < SrcVT) // Truncating cast? - setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N)); - else if (I.getOperand(0)->getType()->isSigned()) - setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DestVT, N)); - else - setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N)); - } else if (isFloatingPoint(DestVT)) { // Int -> FP cast - if (I.getOperand(0)->getType()->isSigned()) - setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N)); - else - setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DestVT, N)); - } else { - assert(0 && "Unknown cast!"); - } - } else if (isFloatingPoint(SrcVT)) { - if (isFloatingPoint(DestVT)) { // FP -> FP cast - if (DestVT < SrcVT) // Rounding cast? - setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N)); - else - setValue(&I, DAG.getNode(ISD::FP_EXTEND, DestVT, N)); - } else if (isInteger(DestVT)) { // FP -> Int cast. - if (I.getType()->isSigned()) - setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DestVT, N)); - else - setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DestVT, N)); - } else { - assert(0 && "Unknown cast!"); - } - } else { - assert(SrcVT == MVT::Vector && "Unknown cast!"); - assert(DestVT != MVT::Vector && "Casts to vector already handled!"); - // This is a cast from a vector to something else. This is always a bit - // convert. Get information about the input vector. + return; + } + MVT::ValueType SrcVT = N.getValueType(); + if (SrcVT == MVT::Vector) { + // This is a cast from a vctor to something else. + // Get information about the input vector. setValue(&I, DAG.getNode(ISD::VBIT_CONVERT, DestVT, N)); + return; } + + // BitCast assures us that source and destination are the same size so this + // is either a BIT_CONVERT or a no-op. + if (DestVT != N.getValueType()) + setValue(&I, DAG.getNode(ISD::BIT_CONVERT, DestVT, N)); // convert types + else + setValue(&I, N); // noop cast. } void SelectionDAGLowering::visitInsertElement(User &I) { @@ -3402,7 +3478,8 @@ static bool OptimizeNoopCopyExpression(CastInst *CI) { while (isa<PHINode>(InsertPt)) ++InsertPt; InsertedCast = - new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt); + CastInst::createInferredCast(CI->getOperand(0), CI->getType(), "", + InsertPt); MadeChange = true; } @@ -3424,9 +3501,10 @@ static Instruction *InsertGEPComputeCode(Instruction *&V, BasicBlock *BB, Value *PtrOffset) { if (V) return V; // Already computed. + // Figure out the insertion point BasicBlock::iterator InsertPt; if (BB == GEPI->getParent()) { - // If insert into the GEP's block, insert right after the GEP. + // If GEP is already inserted into BB, insert right after the GEP. InsertPt = GEPI; ++InsertPt; } else { @@ -3440,11 +3518,14 @@ static Instruction *InsertGEPComputeCode(Instruction *&V, BasicBlock *BB, // operand). if (CastInst *CI = dyn_cast<CastInst>(Ptr)) if (CI->getParent() != BB && isa<PointerType>(CI->getOperand(0)->getType())) - Ptr = new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt); + Ptr = CastInst::createInferredCast(CI->getOperand(0), CI->getType(), "", + InsertPt); // Add the offset, cast it to the right type. Ptr = BinaryOperator::createAdd(Ptr, PtrOffset, "", InsertPt); - return V = new CastInst(Ptr, GEPI->getType(), "", InsertPt); + // Ptr is an integer type, GEPI is pointer type ==> IntToPtr + return V = CastInst::create(Instruction::IntToPtr, Ptr, GEPI->getType(), + "", InsertPt); } /// ReplaceUsesOfGEPInst - Replace all uses of RepPtr with inserted code to @@ -3461,8 +3542,9 @@ static void ReplaceUsesOfGEPInst(Instruction *RepPtr, Value *Ptr, while (!RepPtr->use_empty()) { Instruction *User = cast<Instruction>(RepPtr->use_back()); - // If the user is a Pointer-Pointer cast, recurse. - if (isa<CastInst>(User) && isa<PointerType>(User->getType())) { + // If the user is a Pointer-Pointer cast, recurse. Only BitCast can be + // used for a Pointer-Pointer cast. + if (isa<BitCastInst>(User)) { ReplaceUsesOfGEPInst(User, Ptr, PtrOffset, DefBB, GEPI, InsertedExprs); // Drop the use of RepPtr. The cast is dead. Don't delete it now, else we @@ -3489,7 +3571,8 @@ static void ReplaceUsesOfGEPInst(Instruction *RepPtr, Value *Ptr, if (GEPI->getType() != RepPtr->getType()) { BasicBlock::iterator IP = NewVal; ++IP; - NewVal = new CastInst(NewVal, RepPtr->getType(), "", IP); + // NewVal must be a GEP which must be pointer type, so BitCast + NewVal = new BitCastInst(NewVal, RepPtr->getType(), "", IP); } User->replaceUsesOfWith(RepPtr, NewVal); } @@ -3535,7 +3618,8 @@ static bool OptimizeGEPExpression(GetElementPtrInst *GEPI, // If this is a "GEP X, 0, 0, 0", turn this into a cast. if (!hasConstantIndex && !hasVariableIndex) { - Value *NC = new CastInst(GEPI->getOperand(0), GEPI->getType(), + /// The GEP operand must be a pointer, so must its result -> BitCast + Value *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(), GEPI->getName(), GEPI); GEPI->replaceAllUsesWith(NC); GEPI->eraseFromParent(); @@ -3550,7 +3634,7 @@ static bool OptimizeGEPExpression(GetElementPtrInst *GEPI, // constant offset (which we now know is non-zero) and deal with it later. uint64_t ConstantOffset = 0; const Type *UIntPtrTy = TD->getIntPtrType(); - Value *Ptr = new CastInst(GEPI->getOperand(0), UIntPtrTy, "", GEPI); + Value *Ptr = new PtrToIntInst(GEPI->getOperand(0), UIntPtrTy, "", GEPI); const Type *Ty = GEPI->getOperand(0)->getType(); for (GetElementPtrInst::op_iterator OI = GEPI->op_begin()+1, @@ -3577,7 +3661,7 @@ static bool OptimizeGEPExpression(GetElementPtrInst *GEPI, // Ptr = Ptr + Idx * ElementSize; // Cast Idx to UIntPtrTy if needed. - Idx = new CastInst(Idx, UIntPtrTy, "", GEPI); + Idx = CastInst::createInferredCast(Idx, UIntPtrTy, "", GEPI); uint64_t ElementSize = TD->getTypeSize(Ty); // Mask off bits that should not be set. diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 9b50669777..3c4d9d500d 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -213,7 +213,7 @@ void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) { break; // Found a null terminator, exit. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) FP = CE->getOperand(0); if (Function *F = dyn_cast<Function>(FP)) { // Execute the ctor/dtor function! @@ -299,15 +299,21 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) { return state.getGlobalAddressMap(locked)[GV]; } -/// FIXME: document -/// +/// This function converts a Constant* into a GenericValue. The interesting +/// part is if C is a ConstantExpr. +/// @brief Get a GenericValue for a Constnat* GenericValue ExecutionEngine::getConstantValue(const Constant *C) { + // Declare the result as garbage. GenericValue Result; + + // If its undefined, return the garbage. if (isa<UndefValue>(C)) return Result; - if (ConstantExpr *CE = const_cast<ConstantExpr*>(dyn_cast<ConstantExpr>(C))) { + // If the value is a ConstantExpr + if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { switch (CE->getOpcode()) { case Instruction::GetElementPtr: { + // Compute the index Result = getConstantValue(CE->getOperand(0)); std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end()); uint64_t Offset = @@ -319,24 +325,35 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { Result.LongVal += Offset; return Result; } - case Instruction::Cast: { - // We only need to handle a few cases here. Almost all casts will - // automatically fold, just the ones involving pointers won't. - // + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + break; + case Instruction::PtrToInt: { + Constant *Op = CE->getOperand(0); + GenericValue GV = getConstantValue(Op); + return GV; + } + case Instruction::BitCast: { + // Bit casts are no-ops but we can only return the GV of the operand if + // they are the same basic type (pointer->pointer, packed->packed, etc.) Constant *Op = CE->getOperand(0); GenericValue GV = getConstantValue(Op); - - // Handle cast of pointer to pointer... if (Op->getType()->getTypeID() == C->getType()->getTypeID()) return GV; - - // Handle a cast of pointer to any integral type... - if (isa<PointerType>(Op->getType()) && C->getType()->isIntegral()) - return GV; - - // Handle cast of integer to a pointer... - if (isa<PointerType>(C->getType()) && Op->getType()->isIntegral()) - switch (Op->getType()->getTypeID()) { + break; + } + case Instruction::IntToPtr: { + // IntToPtr casts are just so special. Cast to intptr_t first. + Constant *Op = CE->getOperand(0); + GenericValue GV = getConstantValue(Op); + switch (Op->getType()->getTypeID()) { case Type::BoolTyID: return PTOGV((void*)(uintptr_t)GV.BoolVal); case Type::SByteTyID: return PTOGV((void*)( intptr_t)GV.SByteVal); case Type::UByteTyID: return PTOGV((void*)(uintptr_t)GV.UByteVal); @@ -347,10 +364,9 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { case Type::LongTyID: return PTOGV((void*)( intptr_t)GV.LongVal); case Type::ULongTyID: return PTOGV((void*)(uintptr_t)GV.ULongVal); default: assert(0 && "Unknown integral type!"); - } + } break; } - case Instruction::Add: switch (CE->getOperand(0)->getType()->getTypeID()) { default: assert(0 && "Bad add type!"); abort(); diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 928a819cd0..46d30fb0e2 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -81,8 +81,20 @@ static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, ExecutionContext &SF) { switch (CE->getOpcode()) { - case Instruction::Cast: - return executeCastOperation(CE->getOperand(0), CE->getType(), SF); + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + return executeCastOperation(Instruction::CastOps(CE->getOpcode()), + CE->getOperand(0), CE->getType(), SF); case Instruction::GetElementPtr: return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE), gep_type_end(CE), SF); @@ -1030,12 +1042,15 @@ void Interpreter::visitAShr(ShiftInst &I) { SetValue(&I, Dest, SF); } +#define IMPLEMENT_CAST_START \ + switch (DstTy->getTypeID()) { + #define IMPLEMENT_CAST(DTY, DCTY, STY) \ - case Type::STY##TyID: Dest.DTY##Val = DCTY Src.STY##Val; break; + case Type::STY##TyID: Dest.DTY##Val = DCTY Src.STY##Val; break; -#define IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY) \ +#define IMPLEMENT_CAST_CASE(DESTTY, DESTCTY) \ case Type::DESTTY##TyID: \ - switch (SrcTy->getTypeID()) { \ + switch (SrcTy->getTypeID()) { \ IMPLEMENT_CAST(DESTTY, DESTCTY, Bool); \ IMPLEMENT_CAST(DESTTY, DESTCTY, UByte); \ IMPLEMENT_CAST(DESTTY, DESTCTY, SByte); \ @@ -1045,52 +1060,182 @@ void Interpreter::visitAShr(ShiftInst &I) { IMPLEMENT_CAST(DESTTY, DESTCTY, Int); \ IMPLEMENT_CAST(DESTTY, DESTCTY, ULong); \ IMPLEMENT_CAST(DESTTY, DESTCTY, Long); \ - IMPLEMENT_CAST(DESTTY, DESTCTY, Pointer); - -#define IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY) \ + IMPLEMENT_CAST(DESTTY, DESTCTY, Pointer); \ IMPLEMENT_CAST(DESTTY, DESTCTY, Float); \ - IMPLEMENT_CAST(DESTTY, DESTCTY, Double) - -#define IMPLEMENT_CAST_CASE_END() \ - default: std::cout << "Unhandled cast: " << *SrcTy << " to " << *Ty << "\n"; \ + IMPLEMENT_CAST(DESTTY, DESTCTY, Double) \ + default: \ + std::cout << "Unhandled cast: " \ + << *SrcTy << " to " << *DstTy << "\n"; \ abort(); \ } \ break -#define IMPLEMENT_CAST_CASE(DESTTY, DESTCTY) \ - IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY); \ - IMPLEMENT_CAST_CASE_FP_IMP(DESTTY, DESTCTY); \ - IMPLEMENT_CAST_CASE_END() +#define IMPLEMENT_CAST_END \ + default: std::cout \ + << "Unhandled dest type for cast instruction: " \ + << *DstTy << "\n"; \ + abort(); \ + } -GenericValue Interpreter::executeCastOperation(Value *SrcVal, const Type *Ty, +GenericValue Interpreter::executeCastOperation(Instruction::CastOps opcode, + Value *SrcVal, const Type *DstTy, ExecutionContext &SF) { const Type *SrcTy = SrcVal->getType(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); - switch (Ty->getTypeID()) { - IMPLEMENT_CAST_CASE(UByte , (unsigned char)); - IMPLEMENT_CAST_CASE(SByte , ( signed char)); - IMPLEMENT_CAST_CASE(UShort , (unsigned short)); - IMPLEMENT_CAST_CASE(Short , ( signed short)); - IMPLEMENT_CAST_CASE(UInt , (unsigned int )); - IMPLEMENT_CAST_CASE(Int , ( signed int )); - IMPLEMENT_CAST_CASE(ULong , (uint64_t)); - IMPLEMENT_CAST_CASE(Long , ( int64_t)); - IMPLEMENT_CAST_CASE(Pointer, (PointerTy)); - IMPLEMENT_CAST_CASE(Float , (float)); - IMPLEMENT_CAST_CASE(Double , (double)); - IMPLEMENT_CAST_CASE(Bool , (bool)); - default: - std::cout << "Unhandled dest type for cast instruction: " << *Ty << "\n"; - abort(); + if (opcode == Instruction::Trunc && DstTy->getTypeID() == Type::BoolTyID) { + // For truncations to bool, we must clear the high order bits of the source + switch (SrcTy->getTypeID()) { + case Type::BoolTyID: Src.BoolVal &= 1; break; + case Type::SByteTyID: Src.SByteVal &= 1; break; + case Type::UByteTyID: Src.UByteVal &= 1; break; + case Type::ShortTyID: Src.ShortVal &= 1; break; + case Type::UShortTyID: Src.UShortVal &= 1; break; + case Type::IntTyID: Src.IntVal &= 1; break; + case Type::UIntTyID: Src.UIntVal &= 1; break; + case Type::LongTyID: Src.LongVal &= 1; break; + case Type::ULongTyID: Src.ULongVal &= 1; break; + default: + assert(0 && "Can't trunc a non-integer!"); + break; + } + } else if (opcode == Instruction::SExt && + SrcTy->getTypeID() == Type::BoolTyID) { + // For sign extension from bool, we must extend the source bits. + SrcTy = Type::LongTy; + Src.LongVal = 0 - Src.BoolVal; } + switch (opcode) { + case Instruction::Trunc: // src integer, dest integral (can't be long) + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Bool , (bool)); + IMPLEMENT_CAST_CASE(UByte , (unsigned char)); + IMPLEMENT_CAST_CASE(SByte , ( signed char)); + IMPLEMENT_CAST_CASE(UShort , (unsigned short)); + IMPLEMENT_CAST_CASE(Short , ( signed short)); + IMPLEMENT_CAST_CASE(UInt , (unsigned int )); + IMPLEMENT_CAST_CASE(Int , ( signed int )); + IMPLEMENT_CAST_END + break; + case Instruction::ZExt: // src integral (can't be long), dest integer + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(UByte , (unsigned char)); + IMPLEMENT_CAST_CASE(SByte , (signed char)(unsigned char)); + IMPLEMENT_CAST_CASE(UShort , (unsigned short)); + IMPLEMENT_CAST_CASE(Short , (signed short)(unsigned short)); + IMPLEMENT_CAST_CASE(UInt , (unsigned int )); + IMPLEMENT_CAST_CASE(Int , (signed int)(unsigned int )); + IMPLEMENT_CAST_CASE(ULong , (uint64_t)); + IMPLEMENT_CAST_CASE(Long , (int64_t)(uint64_t)); + IMPLEMENT_CAST_END + break; + case Instruction::SExt: // src integral (can't be long), dest integer + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(UByte , (unsigned char)(signed char)); + IMPLEMENT_CAST_CASE(SByte , (signed char)); + IMPLEMENT_CAST_CASE(UShort , (unsigned short)(signed short)); + IMPLEMENT_CAST_CASE(Short , (signed short)); + IMPLEMENT_CAST_CASE(UInt , (unsigned int )(signed int)); + IMPLEMENT_CAST_CASE(Int , (signed int)); + IMPLEMENT_CAST_CASE(ULong , (uint64_t)(int64_t)); + IMPLEMENT_CAST_CASE(Long , (int64_t)); + IMPLEMENT_CAST_END + break; + case Instruction::FPTrunc: // src double, dest float + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Float , (float)); + IMPLEMENT_CAST_END + break; + case Instruction::FPExt: // src float, dest double + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Double , (double)); + IMPLEMENT_CAST_END + break; + case Instruction::UIToFP: // src integral, dest floating + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Float , (float)(uint64_t)); + IMPLEMENT_CAST_CASE(Double , (double)(uint64_t)); + IMPLEMENT_CAST_END + break; + case Instruction::SIToFP: // src integeral, dest floating + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Float , (float)(int64_t)); + IMPLEMENT_CAST_CASE(Double , (double)(int64_t)); + IMPLEMENT_CAST_END + break; + case Instruction::FPToUI: // src floating, dest integral + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Bool , (bool)); + IMPLEMENT_CAST_CASE(UByte , (unsigned char)); + IMPLEMENT_CAST_CASE(SByte , (signed char)(unsigned char)); + IMPLEMENT_CAST_CASE(UShort , (unsigned short)); + IMPLEMENT_CAST_CASE(Short , (signed short)(unsigned short)); + IMPLEMENT_CAST_CASE(UInt , (unsigned int )); + IMPLEMENT_CAST_CASE(Int , (signed int)(unsigned int )); + IMPLEMENT_CAST_CASE(ULong , (uint64_t)); + IMPLEMENT_CAST_CASE(Long , (int64_t)(uint64_t)); + IMPLEMENT_CAST_END + break; + case Instruction::FPToSI: // src floating, dest integral + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Bool , (bool)); + IMPLEMENT_CAST_CASE(UByte , (unsigned char)(signed char)); + IMPLEMENT_CAST_CASE(SByte , (signed char)); + IMPLEMENT_CAST_CASE(UShort , (unsigned short)(signed short)); + IMPLEMENT_CAST_CASE(Short , (signed short)); + IMPLEMENT_CAST_CASE(UInt , (unsigned int )(signed int)); + IMPLEMENT_CAST_CASE(Int , (signed int)); + IMPLEMENT_CAST_CASE(ULong , (uint64_t)(int64_t)); + IMPLEMENT_CAST_CASE(Long , (int64_t)); + IMPLEMENT_CAST_END + break; + case Instruction::PtrToInt: // src pointer, dest integral + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Bool , (bool)); + IMPLEMENT_CAST_CASE(UByte , (unsigned char)); + IMPLEMENT_CAST_CASE(SByte , (signed char)(unsigned char)); + IMPLEMENT_CAST_CASE(UShort , (unsigned short)); + IMPLEMENT_CAST_CASE(Short , (signed short)(unsigned short)); + IMPLEMENT_CAST_CASE(UInt , (unsigned int)); + IMPLEMENT_CAST_CASE(Int , (signed int)(unsigned int)); + IMPLEMENT_CAST_CASE(ULong , (uint64_t)); + IMPLEMENT_CAST_CASE(Long , (int64_t)(uint64_t)); + IMPLEMENT_CAST_END + break; + case Instruction::IntToPtr: // src integral, dest pointer + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Pointer, (PointerTy)); + IMPLEMENT_CAST_END + break; + case Instruction::BitCast: // src any, dest any (same size) + IMPLEMENT_CAST_START + IMPLEMENT_CAST_CASE(Bool , (bool)); + IMPLEMENT_CAST_CASE(UByte , (unsigned char)); + IMPLEMENT_CAST_CASE(SByte , ( signed char)); + IMPLEMENT_CAST_CASE(UShort , (unsigned short)); + IMPLEMENT_CAST_CASE(Short , ( signed short)); + IMPLEMENT_CAST_CASE(UInt , (unsigned int)); + IMPLEMENT_CAST_CASE(Int , ( signed int)); + IMPLEMENT_CAST_CASE(ULong , (uint64_t)); + IMPLEMENT_CAST_CASE(Long , ( int64_t)); + IMPLEMENT_CAST_CASE(Pointer, (PointerTy)); + IMPLEMENT_CAST_CASE(Float , (float)); + IMPLEMENT_CAST_CASE(Double , (double)); + IMPLEMENT_CAST_END + break; + default: + std::cout + << "Invalid cast opcode for cast instruction: " << opcode << "\n"; + abort(); + } return Dest; } void Interpreter::visitCastInst(CastInst &I) { ExecutionContext &SF = ECStack.back(); - SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF); + SetValue(&I, executeCastOperation(I.getOpcode(), I.getOperand(0), + I.getType(), SF), SF); } #define IMPLEMENT_VAARG(TY) \ diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index ced624f601..67fb703441 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -192,8 +192,8 @@ private: // Helper functions void initializeExternalFunctions(); GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF); GenericValue getOperandValue(Value *V, ExecutionContext &SF); - GenericValue executeCastOperation(Value *SrcVal, const Type *Ty, - ExecutionContext &SF); + GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal, + const Type *Ty, ExecutionContext &SF); void popStackAndReturnValueToCaller(const Type *RetTy, GenericValue Result); }; diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index ba3b7ca8b0..bcc5fbf60a 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -137,6 +137,7 @@ namespace { void printBasicBlock(BasicBlock *BB); void printLoop(Loop *L); + void printCast(unsigned opcode, const Type *SrcTy, const Type *DstTy); void printConstant(Constant *CPV); void printConstantWithCast(Constant *CPV, unsigned Opcode); bool printConstExprCast(const ConstantExpr *CE); @@ -560,15 +561,76 @@ static bool isFPCSafeToPrint(const ConstantFP *CFP) { #endif } +/// Print out the casting for a cast operation. This does the double casting +/// necessary for conversion to the destination type, if necessary. +/// @returns true if a closing paren is necessary +/// @brief Print a cast +void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) { + Out << '('; + printType(Out, DstTy); + Out << ')'; + switch (opc) { + case Instruction::UIToFP: + case Instruction::ZExt: + if (SrcTy->isSigned()) { + Out << '('; + printType(Out, SrcTy->getUnsignedVersion()); + Out << ')'; + } + break; + case Instruction::SIToFP: + case Instruction::SExt: + if (SrcTy->isUnsigned()) { + Out << '('; + printType(Out, SrcTy->getSignedVersion()); + Out << ')'; + } + break; + case Instruction::IntToPtr: + case Instruction::PtrToInt: + // Avoid "cast to pointer from integer of different size" warnings + Out << "(unsigned long)"; + break; + case Instruction::Trunc: + case Instruction::BitCast: + case Instruction::FPExt: + case Instruction::FPTrunc: + case Instruction::FPToSI: + case Instruction::FPToUI: + default: + break; + } +} + // printConstant - The LLVM Constant to C Constant converter. void CWriter::printConstant(Constant *CPV) { if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) { switch (CE->getOpcode()) { - case Instruction::Cast: - Out << "(("; - printType(Out, CPV->getType()); - Out << ')'; + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + Out << "("; + printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType()); + if (CE->getOpcode() == Instruction::SExt && + CE->getOperand(0)->getType() == Type::BoolTy) { + // Make sure we really sext from bool here by subtracting from 0 + Out << "0-"; + } printConstant(CE->getOperand(0)); + if (CE->getOpcode() == Instruction::Trunc && + CE->getType() == Type::BoolTy) { + // Make sure we really truncate to bool here by anding with 1 + Out << "&1u"; + } Out << ')'; return; @@ -829,14 +891,31 @@ void CWriter::printConstant(Constant *CPV) { // care of detecting that case and printing the cast for the ConstantExpr. bool CWriter::printConstExprCast(const ConstantExpr* CE) { bool NeedsExplicitCast = false; - const Type* Ty = CE->getOperand(0)->getType(); + const Type *Ty = CE->getOperand(0)->getType(); switch (CE->getOpcode()) { case Instruction::LShr: case Instruction::URem: - case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break; + case Instruction::UDiv: + NeedsExplicitCast = Ty->isSigned(); break; case Instruction::AShr: case Instruction::SRem: - case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::SDiv: + NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::Trunc: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + Ty = CE->getType(); + NeedsExplicitCast = true; + break; default: break; } if (NeedsExplicitCast) { @@ -860,7 +939,8 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { // Based on the Opcode for which this Constant is being written, determine // the new type to which the operand should be casted by setting the value - // of OpTy. If we change OpTy, also set shouldCast to true. + // of OpTy. If we change OpTy, also set shouldCast to true so it gets + // casted below. switch (Opcode) { default: // for most instructions, it doesn't matter @@ -885,7 +965,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { break; } - // Write out the casted constnat if we should, otherwise just write the + // Write out the casted constant if we should, otherwise just write the // operand. if (shouldCast) { Out << "(("; @@ -918,7 +998,7 @@ void CWriter::writeOperandInternal(Value *Operand) { void CWriter::writeOperand(Value *Operand) { if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand)) - Out << "(&"; // Global variables are references as their addresses by llvm + Out << "(&"; // Global variables are referenced as their addresses by llvm writeOperandInternal(Operand); @@ -932,14 +1012,31 @@ void CWriter::writeOperand(Value *Operand) { // for the Instruction. bool CWriter::writeInstructionCast(const Instruction &I) { bool NeedsExplicitCast = false; - const Type* Ty = I.getOperand(0)->getType(); + const Type *Ty = I.getOperand(0)->getType(); switch (I.getOpcode()) { case Instruction::LShr: case Instruction::URem: - case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break; + case Instruction::UDiv: + NeedsExplicitCast = Ty->isSigned(); break; case Instruction::AShr: case Instruction::SRem: - case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::SDiv: + NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::Trunc: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + Ty = I.getType(); + NeedsExplicitCast = true; + break; default: break; } if (NeedsExplicitCast) { @@ -1136,7 +1233,7 @@ static void FindStaticTors(GlobalVariable *GV, std::set<Function*> &StaticTors){ return; // Found a null terminator, exit printing. Constant *FP = CS->getOperand(1); if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) FP = CE->getOperand(0); if (Function *F = dyn_cast<Function>(FP)) StaticTors.insert(F); @@ -1854,22 +1951,20 @@ void CWriter::visitBinaryOperator(Instruction &I) { } void CWriter::visitCastInst(CastInst &I) { - if (I.getType() == Type::BoolTy) { - Out << '('; - writeOperand(I.getOperand(0)); - Out << " != 0)"; - return; - } + const Type *DstTy = I.getType(); + const Type *SrcTy = I.getOperand(0)->getType(); Out << '('; - printType(Out, I.getType()); - Out << ')'; - if (isa<PointerType>(I.getType())&&I.getOperand(0)->getType()->isIntegral() || - isa<PointerType>(I.getOperand(0)->getType())&&I.getType()->isIntegral()) { - // Avoid "cast to pointer from integer of different size" warnings - Out << "(long)"; + printCast(I.getOpcode(), SrcTy, DstTy); + if (I.getOpcode() == Instruction::SExt && SrcTy == Type::BoolTy) { + // Make sure we really get a sext from bool by subtracing the bool from 0 + Out << "0-"; } - writeOperand(I.getOperand(0)); + if (I.getOpcode() == Instruction::Trunc && DstTy == Type::BoolTy) { + // Make sure we really get a trunc to bool by anding the operand with 1 + Out << "&1u"; + } + Out << ')'; } void CWriter::visitSelectInst(SelectInst &I) { @@ -2076,7 +2171,7 @@ void CWriter::visitCallInst(CallInst &I) { // match exactly. // if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Callee)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) if (Function *RF = dyn_cast<Function>(CE->getOperand(0))) { NeedsCast = true; Callee = RF; diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index ba3b7ca8b0..bcc5fbf60a 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -137,6 +137,7 @@ namespace { void printBasicBlock(BasicBlock *BB); void printLoop(Loop *L); + void printCast(unsigned opcode, const Type *SrcTy, const Type *DstTy); void printConstant(Constant *CPV); void printConstantWithCast(Constant *CPV, unsigned Opcode); bool printConstExprCast(const ConstantExpr *CE); @@ -560,15 +561,76 @@ static bool isFPCSafeToPrint(const ConstantFP *CFP) { #endif } +/// Print out the casting for a cast operation. This does the double casting +/// necessary for conversion to the destination type, if necessary. +/// @returns true if a closing paren is necessary +/// @brief Print a cast +void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) { + Out << '('; + printType(Out, DstTy); + Out << ')'; + switch (opc) { + case Instruction::UIToFP: + case Instruction::ZExt: + if (SrcTy->isSigned()) { + Out << '('; + printType(Out, SrcTy->getUnsignedVersion()); + Out << ')'; + } + break; + case Instruction::SIToFP: + case Instruction::SExt: + if (SrcTy->isUnsigned()) { + Out << '('; + printType(Out, SrcTy->getSignedVersion()); + Out << ')'; + } + break; + case Instruction::IntToPtr: + case Instruction::PtrToInt: + // Avoid "cast to pointer from integer of different size" warnings + Out << "(unsigned long)"; + break; + case Instruction::Trunc: + case Instruction::BitCast: + case Instruction::FPExt: + case Instruction::FPTrunc: + case Instruction::FPToSI: + case Instruction::FPToUI: + default: + break; + } +} + // printConstant - The LLVM Constant to C Constant converter. void CWriter::printConstant(Constant *CPV) { if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) { switch (CE->getOpcode()) { - case Instruction::Cast: - Out << "(("; - printType(Out, CPV->getType()); - Out << ')'; + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + Out << "("; + printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType()); + if (CE->getOpcode() == Instruction::SExt && + CE->getOperand(0)->getType() == Type::BoolTy) { + // Make sure we really sext from bool here by subtracting from 0 + Out << "0-"; + } printConstant(CE->getOperand(0)); + if (CE->getOpcode() == Instruction::Trunc && + CE->getType() == Type::BoolTy) { + // Make sure we really truncate to bool here by anding with 1 + Out << "&1u"; + } Out << ')'; return; @@ -829,14 +891,31 @@ void CWriter::printConstant(Constant *CPV) { // care of detecting that case and printing the cast for the ConstantExpr. bool CWriter::printConstExprCast(const ConstantExpr* CE) { bool NeedsExplicitCast = false; - const Type* Ty = CE->getOperand(0)->getType(); + const Type *Ty = CE->getOperand(0)->getType(); switch (CE->getOpcode()) { case Instruction::LShr: case Instruction::URem: - case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break; + case Instruction::UDiv: + NeedsExplicitCast = Ty->isSigned(); break; case Instruction::AShr: case Instruction::SRem: - case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::SDiv: + NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::Trunc: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + Ty = CE->getType(); + NeedsExplicitCast = true; + break; default: break; } if (NeedsExplicitCast) { @@ -860,7 +939,8 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { // Based on the Opcode for which this Constant is being written, determine // the new type to which the operand should be casted by setting the value - // of OpTy. If we change OpTy, also set shouldCast to true. + // of OpTy. If we change OpTy, also set shouldCast to true so it gets + // casted below. switch (Opcode) { default: // for most instructions, it doesn't matter @@ -885,7 +965,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { break; } - // Write out the casted constnat if we should, otherwise just write the + // Write out the casted constant if we should, otherwise just write the // operand. if (shouldCast) { Out << "(("; @@ -918,7 +998,7 @@ void CWriter::writeOperandInternal(Value *Operand) { void CWriter::writeOperand(Value *Operand) { if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand)) - Out << "(&"; // Global variables are references as their addresses by llvm + Out << "(&"; // Global variables are referenced as their addresses by llvm writeOperandInternal(Operand); @@ -932,14 +1012,31 @@ void CWriter::writeOperand(Value *Operand) { // for the Instruction. bool CWriter::writeInstructionCast(const Instruction &I) { bool NeedsExplicitCast = false; - const Type* Ty = I.getOperand(0)->getType(); + const Type *Ty = I.getOperand(0)->getType(); switch (I.getOpcode()) { case Instruction::LShr: case Instruction::URem: - case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break; + case Instruction::UDiv: + NeedsExplicitCast = Ty->isSigned(); break; case Instruction::AShr: case Instruction::SRem: - case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::SDiv: + NeedsExplicitCast = Ty->isUnsigned(); break; + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::Trunc: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + Ty = I.getType(); + NeedsExplicitCast = true; + break; default: break; } if (NeedsExplicitCast) { @@ -1136,7 +1233,7 @@ static void FindStaticTors(GlobalVariable *GV, std::set<Function*> &StaticTors){ return; // Found a null terminator, exit printing. Constant *FP = CS->getOperand(1); if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) FP = CE->getOperand(0); if (Function *F = dyn_cast<Function>(FP)) StaticTors.insert(F); @@ -1854,22 +1951,20 @@ void CWriter::visitBinaryOperator(Instruction &I) { } void CWriter::visitCastInst(CastInst &I) { - if (I.getType() == Type::BoolTy) { - Out << '('; - writeOperand(I.getOperand(0)); - Out << " != 0)"; - return; - } + const Type *DstTy = I.getType(); + const Type *SrcTy = I.getOperand(0)->getType(); Out << '('; - printType(Out, I.getType()); - Out << ')'; - if (isa<PointerType>(I.getType())&&I.getOperand(0)->getType()->isIntegral() || - isa<PointerType>(I.getOperand(0)->getType())&&I.getType()->isIntegral()) { - // Avoid "cast to pointer from integer of different size" warnings - Out << "(long)"; + printCast(I.getOpcode(), SrcTy, DstTy); + if (I.getOpcode() == Instruction::SExt && SrcTy == Type::BoolTy) { + // Make sure we really get a sext from bool by subtracing the bool from 0 + Out << "0-"; } - writeOperand(I.getOperand(0)); + if (I.getOpcode() == Instruction::Trunc && DstTy == Type::BoolTy) { + // Make sure we really get a trunc to bool by anding the operand with 1 + Out << "&1u"; + } + Out << ')'; } void CWriter::visitSelectInst(SelectInst &I) { @@ -2076,7 +2171,7 @@ void CWriter::visitCallInst(CallInst &I) { // match exactly. // if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Callee)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) if (Function *RF = dyn_cast<Function>(CE->getOperand(0))) { NeedsCast = true; Callee = RF; diff --git a/lib/Transforms/ExprTypeConvert.cpp b/lib/Transforms/ExprTypeConvert.cpp index 7c336d5b4b..39f21ead85 100644 --- a/lib/Transforms/ExprTypeConvert.cpp +++ b/lib/Transforms/ExprTypeConvert.cpp @@ -52,12 +52,10 @@ bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty, if (I == 0) return false; // Otherwise, we can't convert! switch (I->getOpcode()) { - case Instruction::Cast: - // We can convert the expr if the cast destination type is losslessly - // convertible to the requested type. - if (!Ty->isLosslesslyConvertibleTo(I->getType())) return false; - - // We also do not allow conversion of a cast that casts from a ptr to array + case Instruction::BitCast: + if (!cast<BitCastInst>(I)->isLosslessCast()) + return false; + // We do not allow conversion of a cast that casts from a ptr to array // of X to a *X. For example: cast [4 x %List *] * %val to %List * * // if (const PointerType *SPT = @@ -66,6 +64,7 @@ bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty, if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType())) if (AT->getElementType() == DPT->getElementType()) return false; + // Otherwise it is a lossless cast and we can allow it break; case Instruction::Add: @@ -227,9 +226,9 @@ Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty, Constant *Dummy = Constant::getNullValue(Ty); switch (I->getOpcode()) { - case Instruction::Cast: + case Instruction::BitCast: assert(VMC.NewCasts.count(ValueHandle(VMC, I)) == 0); - Res = new CastInst(I->getOperand(0), Ty, Name); + Res = CastInst::createInferredCast(I->getOperand(0), Ty, Name); VMC.NewCasts.insert(ValueHandle(VMC, Res)); break; @@ -307,7 +306,8 @@ Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty, Indices.pop_back(); if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) { if (Indices.size() == 0) - Res = new CastInst(GEP->getPointerOperand(), BaseType); // NOOP CAST + // We want to no-op cast this so use BitCast + Res = new BitCastInst(GEP->getPointerOperand(), BaseType); else Res = new GetElementPtrInst(GEP->getPointerOperand(), Indices, Name); break; @@ -411,10 +411,6 @@ bool llvm::ValueConvertibleToType(Value *V, const Type *Ty, return true; } - - - - // OperandConvertibleToType - Return true if it is possible to convert operand // V of User (instruction) U to the specified type. This is true iff it is // possible to change the specified instruction to accept this. CTMap is a map @@ -431,29 +427,18 @@ static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, return false; Instruction *I = dyn_cast<Instruction>(U); - if (I == 0) return false; // We can't convert! + if (I == 0) return false; // We can't convert non-instructions! switch (I->getOpcode()) { - case Instruction::Cast: + case Instruction::BitCast: assert(I->getOperand(0) == V); // We can convert the expr if the cast destination type is losslessly - // convertible to the requested type. - // Also, do not change a cast that is a noop cast. For all intents and - // purposes it should be eliminated. - if (!Ty->isLosslesslyConvertibleTo(I->getOperand(0)->getType()) || + // convertible to the requested type. Also, do not change a cast that + // is a noop cast. For all intents and purposes it should be eliminated. + if (!cast<BitCastInst>(I)->isLosslessCast() || I->getType() == I->getOperand(0)->getType()) return false; - // Do not allow a 'cast ushort %V to uint' to have it's first operand be - // converted to a 'short' type. Doing so changes the way sign promotion - // happens, and breaks things. Only allow the cast to take place if the - // signedness doesn't change... or if the current cast is not a lossy - // conversion. - // - if (!I->getType()->isLosslesslyConvertibleTo(I->getOperand(0)->getType()) && - I->getOperand(0)->getType()->isSigned() != Ty->isSigned()) - return false; - // We also do not allow conversion of a cast that casts from a ptr to array // of X to a *X. For example: cast [4 x %List *] * %val to %List * * // @@ -642,7 +627,8 @@ static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, // arguments if possible. // for (unsigned i = 0, NA = FTy->getNumParams(); i < NA; ++i) - if (!FTy->getParamType(i)->isLosslesslyConvertibleTo(I->getOperand(i+1)->getType())) + if (!FTy->getParamType(i)->canLosslesslyBitCastTo( + I->getOperand(i+1)->getType())) return false; // Operands must have compatible types! // Okay, at this point, we know that all of the arguments can be @@ -662,7 +648,7 @@ static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, // If we get this far, we know the value is in the varargs section of the // function! We can convert if we don't reinterpret the value... // - return Ty->isLosslesslyConvertibleTo(V->getType()); + return Ty->canLosslesslyBitCastTo(V->getType()); } } return false; @@ -718,19 +704,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, Constant::getNullValue(NewTy) : 0; switch (I->getOpcode()) { - case Instruction::Cast: - if (VMC.NewCasts.count(ValueHandle(VMC, I))) { - // This cast has already had it's value converted, causing a new cast to - // be created. We don't want to create YET ANOTHER cast instruction - // representing the original one, so just modify the operand of this cast - // instruction, which we know is newly created. - I->setOperand(0, NewVal); - I->setName(Name); // give I its name back - return; - - } else { - Res = new CastInst(NewVal, I->getType(), Name); - } + case Instruction::BitCast: + Res = CastInst::createInferredCast(NewVal, I->getType(), Name); break; case Instruction::Add: @@ -895,9 +870,9 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, for (unsigned i = 0; i != NewTy->getNumParams(); ++i) if (Params[i]->getType() != NewTy->getParamType(i)) { // Create a cast to convert it to the right type, we know that this - // is a lossless cast... + // is a no-op cast... // - Params[i] = new CastInst(Params[i], NewTy->getParamType(i), + Params[i] = new BitCastInst(Params[i], NewTy->getParamType(i), "callarg.cast." + Params[i]->getName(), It); } diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index bdec082cd0..4ddc071681 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -329,7 +329,7 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) { if (Init) SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); Changed |= CleanupConstantGlobalUsers(CE, SubInit); - } else if (CE->getOpcode() == Instruction::Cast && + } else if (CE->getOpcode() == Instruction::BitCast && isa<PointerType>(CE->getType())) { // Pointer cast, delete any stores and memsets to the global. Changed |= CleanupConstantGlobalUsers(CE, 0); @@ -1174,7 +1174,7 @@ static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { LoadInst *NLI = new LoadInst(NewGV, Name+".b", LI); Value *NSI; if (IsOneZero) - NSI = new CastInst(NLI, LI->getType(), Name, LI); + NSI = CastInst::createInferredCast(NLI, LI->getType(), Name, LI); else NSI = new SelectInst(NLI, OtherVal, InitVal, Name, LI); LI->replaceAllUsesWith(NSI); diff --git a/lib/Transforms/IPO/IndMemRemoval.cpp b/lib/Transforms/IPO/IndMemRemoval.cpp index c993f70cec..0779a5414f 100644 --- a/lib/Transforms/IPO/IndMemRemoval.cpp +++ b/lib/Transforms/IPO/IndMemRemoval.cpp @@ -74,7 +74,8 @@ bool IndMemRemPass::runOnModule(Module &M) { GlobalValue::LinkOnceLinkage, "malloc_llvm_bounce", &M); BasicBlock* bb = new BasicBlock("entry",FN); - Instruction* c = new CastInst(FN->arg_begin(), Type::UIntTy, "c", bb); + Instruction* c = + CastInst::createInferredCast(FN->arg_begin(), Type::UIntTy, "c", bb); Instruction* a = new MallocInst(Type::SByteTy, c, "m", bb); new ReturnInst(a, bb); ++NumBounce; diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp index c4b033c8c1..52d75735ef 100644 --- a/lib/Transforms/IPO/InlineSimple.cpp +++ b/lib/Transforms/IPO/InlineSimple.cpp @@ -141,14 +141,11 @@ void FunctionInfo::analyzeFunction(Function *F) { II != E; ++II) { if (isa<DbgInfoIntrinsic>(II)) continue; // Debug intrinsics don't count. - // Noop casts don't count. + // Noop casts, including ptr <-> int, don't count. if (const CastInst *CI = dyn_cast<CastInst>(II)) { - const Type *OpTy = CI->getOperand(0)->getType(); - if (CI->getType()->isLosslesslyConvertibleTo(OpTy)) + if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) || + isa<PtrToIntInst>(CI)) continue; - if ((isa<PointerType>(CI->getType()) && OpTy->isInteger()) || - (isa<PointerType>(OpTy) && CI->getType()->isInteger())) - continue; // ptr <-> int is *probably* noop cast. } else if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(II)) { // If a GEP has all constant indices, it will probably be folded with diff --git a/lib/Transforms/IPO/LowerSetJmp.cpp b/lib/Transforms/IPO/LowerSetJmp.cpp index e6ff5c977a..3aac392091 100644 --- a/lib/Transforms/IPO/LowerSetJmp.cpp +++ b/lib/Transforms/IPO/LowerSetJmp.cpp @@ -259,7 +259,8 @@ void LowerSetJmp::TransformLongJmpCall(CallInst* Inst) // same parameters as "longjmp", except that the buffer is cast to a // char*. It returns "void", so it doesn't need to replace any of // Inst's uses and doesn't get a name. - CastInst* CI = new CastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst); + CastInst* CI = + new BitCastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst); new CallInst(ThrowLongJmp, make_vector<Value*>(CI, Inst->getOperand(2), 0), "", Inst); @@ -375,7 +376,8 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst) // Add this setjmp to the setjmp map. const Type* SBPTy = PointerType::get(Type::SByteTy); - CastInst* BufPtr = new CastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst); + CastInst* BufPtr = + new BitCastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst); new CallInst(AddSJToMap, make_vector<Value*>(GetSetJmpMap(Func), BufPtr, ConstantInt::get(Type::UIntTy, diff --git a/lib/Transforms/IPO/RaiseAllocations.cpp b/lib/Transforms/IPO/RaiseAllocations.cpp index 188b7f527f..584a2e98b0 100644 --- a/lib/Transforms/IPO/RaiseAllocations.cpp +++ b/lib/Transforms/IPO/RaiseAllocations.cpp @@ -140,7 +140,9 @@ bool RaiseAllocations::runOnModule(Module &M) { // If no prototype was provided for malloc, we may need to cast the // source size. if (Source->getType() != Type::UIntTy) - Source = new CastInst(Source, Type::UIntTy, "MallocAmtCast", I); + Source = + CastInst::createInferredCast(Source, Type::UIntTy, + "MallocAmtCast", I); std::string Name(I->getName()); I->setName(""); MallocInst *MI = new MallocInst(Type::SByteTy, Source, Name, I); @@ -160,7 +162,7 @@ bool RaiseAllocations::runOnModule(Module &M) { Users.insert(Users.end(), GV->use_begin(), GV->use_end()); EqPointers.push_back(GV); } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) { - if (CE->getOpcode() == Instruction::Cast) { + if (CE->isCast()) { Users.insert(Users.end(), CE->use_begin(), CE->use_end()); EqPointers.push_back(CE); } @@ -191,8 +193,8 @@ bool RaiseAllocations::runOnModule(Module &M) { // Value *Source = *CS.arg_begin(); if (!isa<PointerType>(Source->getType())) - Source = new CastInst(Source, PointerType::get(Type::SByteTy), - "FreePtrCast", I); + Source = CastInst::createInferredCast( + Source, PointerType::get(Type::SByteTy), "FreePtrCast", I); new FreeInst(Source, I); // If the old instruction was an invoke, add an unconditional branch @@ -211,7 +213,7 @@ bool RaiseAllocations::runOnModule(Module &M) { Users.insert(Users.end(), GV->use_begin(), GV->use_end()); EqPointers.push_back(GV); } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) { - if (CE->getOpcode() == Instruction::Cast) { + if (CE->isCast()) { Users.insert(Users.end(), CE->use_begin(), CE->use_end()); EqPointers.push_back(CE); } diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp index af117094d6..fb22a2f139 100644 --- a/lib/Transforms/IPO/SimplifyLibCalls.cpp +++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp @@ -650,7 +650,8 @@ public: LoadInst* load = new LoadInst(CastToCStr(s2,*ci), ci->getName()+".load",ci); CastInst* cast = - new CastInst(load,Type::IntTy,ci->getName()+".int",ci); + CastInst::create(Instruction::SExt, load, Type::IntTy, + ci->getName()+".int", ci); ci->replaceAllUsesWith(cast); ci->eraseFromParent(); return true; @@ -667,7 +668,8 @@ public: LoadInst* load = new LoadInst(CastToCStr(s1,*ci),ci->getName()+".val",ci); CastInst* cast = - new CastInst(load,Type::IntTy,ci->getName()+".int",ci); + CastInst::create(Instruction::SExt, load, Type::IntTy, + ci->getName()+".int", ci); ci->replaceAllUsesWith(cast); ci->eraseFromParent(); return true; @@ -741,7 +743,8 @@ public: // strncmp("",x) -> *x LoadInst* load = new LoadInst(s1,ci->getName()+".load",ci); CastInst* cast = - new CastInst(load,Type::IntTy,ci->getName()+".int",ci); + CastInst::create(Instruction::SExt, load, Type::IntTy, + ci->getName()+".int", ci); ci->replaceAllUsesWith(cast); ci->eraseFromParent(); return true; @@ -757,7 +760,8 @@ public: // strncmp(x,"") -> *x LoadInst* load = new LoadInst(s2,ci->getName()+".val",ci); CastInst* cast = - new CastInst(load,Type::IntTy,ci->getName()+".int",ci); + CastInst::create(Instruction::SExt, load, Type::IntTy, + ci->getName()+".int", ci); ci->replaceAllUsesWith(cast); ci->eraseFromParent(); return true; @@ -997,13 +1001,15 @@ struct memcmpOptimization : public LibCallOptimization { case 1: { // memcmp(S1,S2,1) -> *(ubyte*)S1 - *(ubyte*)S2 const Type *UCharPtr = PointerType::get(Type::UByteTy); - CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI); - CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI); + CastInst *Op1Cast = CastInst::create( + Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI); + CastInst *Op2Cast = CastInst::create( + Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI); Value *S1V = new LoadInst(Op1Cast, LHS->getName()+".val", CI); Value *S2V = new LoadInst(Op2Cast, RHS->getName()+".val", CI); Value *RV = BinaryOperator::createSub(S1V, S2V, CI->getName()+".diff",CI); if (RV->getType() != CI->getType()) - RV = new CastInst(RV, CI->getType(), RV->getName(), CI); + RV = CastInst::createInferredCast(RV, CI->getType(), RV->getName(), CI); CI->replaceAllUsesWith(RV); CI->eraseFromParent(); return true; @@ -1014,8 +1020,10 @@ struct memcmpOptimization : public LibCallOptimization { // memcmp(S1,S2,2) -> S1[0]-S2[0] | S1[1]-S2[1] iff only ==/!= 0 matters const Type *UCharPtr = PointerType::get(Type::UByteTy); - CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI); - CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI); + CastInst *Op1Cast = CastInst::create( + Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI); + CastInst *Op2Cast = CastInst::create( + Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI); Value *S1V1 = new LoadInst(Op1Cast, LHS->getName()+".val1", CI); Value *S2V1 = new LoadInst(Op2Cast, RHS->getName()+".val1", CI); Value *D1 = BinaryOperator::createSub(S1V1, S2V1, @@ -1029,7 +1037,8 @@ struct memcmpOptimization : public LibCallOptimization { CI->getName()+".d1", CI); Value *Or = BinaryOperator::createOr(D1, D2, CI->getName()+".res", CI); if (Or->getType() != CI->getType()) - Or = new CastInst(Or, CI->getType(), Or->getName(), CI); + Or = CastInst::createInferredCast(Or, CI->getType(), Or->getName(), + CI); CI->replaceAllUsesWith(Or); CI->eraseFromParent(); return true; @@ -1101,10 +1110,10 @@ struct LLVMMemCpyMoveOptzn : public LibCallOptimization { } // Cast source and dest to the right sized primitive and then load/store - CastInst* SrcCast = - new CastInst(src,PointerType::get(castType),src->getName()+".cast",ci); - CastInst* DestCast = - new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci); + CastInst* SrcCast = CastInst::create(Instruction::BitCast, + src, PointerType::get(castType), src->getName()+".cast", ci); + CastInst* DestCast = CastInst::create(Instruction::BitCast, + dest, PointerType::get(castType),dest->getName()+".cast", ci); LoadInst* LI = new LoadInst(SrcCast,SrcCast->getName()+".val",ci); new StoreInst(LI, DestCast, ci); ci->eraseFromParent(); @@ -1213,8 +1222,8 @@ struct LLVMMemSetOptimization : public LibCallOptimization { } // Cast dest to the right sized primitive and then load/store - CastInst* DestCast = - new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci); + CastInst* DestCast = CastInst::createInferredCast( + dest, PointerType::get(castType), dest->getName()+".cast", ci); new StoreInst(ConstantInt::get(castType,fill_value),DestCast, ci); ci->eraseFromParent(); return true; @@ -1356,8 +1365,8 @@ public: Function* putchar_func = SLC.get_putchar(); if (!putchar_func) return false; - CastInst* cast = new CastInst(ci->getOperand(2), Type::IntTy, - CI->getName()+".int", ci); + CastInst* cast = CastInst::createInferredCast( + ci->getOperand(2), Type::IntTy, CI->getName()+".int", ci); new CallInst(putchar_func, cast, "", ci); ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy, 1)); break; @@ -1490,8 +1499,8 @@ public: Function* fputc_func = SLC.get_fputc(FILEptr_type); if (!fputc_func) return false; - CastInst* cast = new CastInst(ci->getOperand(3), Type::IntTy, - CI->getName()+".int", ci); + CastInst* cast = CastInst::createInferredCast( + ci->getOperand(3), Type::IntTy, CI->getName()+".int", ci); new CallInst(fputc_func,cast,ci->getOperand(1),"",ci); ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,1)); break; @@ -1597,7 +1606,8 @@ public: ConstantInt::get(Len->getType(), 1), Len->getName()+"1", ci); if (Len1->getType() != SLC.getIntPtrType()) - Len1 = new CastInst(Len1, SLC.getIntPtrType(), Len1->getName(), ci); + Len1 = CastInst::createInferredCast( + Len1, SLC.getIntPtrType(), Len1->getName(), ci); std::vector<Value*> args; args.push_back(CastToCStr(ci->getOperand(1), *ci)); args.push_back(CastToCStr(ci->getOperand(3), *ci)); @@ -1608,7 +1618,8 @@ public: // The strlen result is the unincremented number of bytes in the string. if (!ci->use_empty()) { if (Len->getType() != ci->getType()) - Len = new CastInst(Len, ci->getType(), Len->getName(), ci); + Len = CastInst::createInferredCast( + Len, ci->getType(), Len->getName(), ci); ci->replaceAllUsesWith(Len); } ci->eraseFromParent(); @@ -1616,7 +1627,8 @@ public: } case 'c': { // sprintf(dest,"%c",chr) -> store chr, dest - CastInst* cast = new CastInst(ci->getOperand(3),Type::SByteTy,"char",ci); + CastInst* cast = CastInst::createInferredCast( + ci->getOperand(3), Type::SByteTy, "char", ci); new StoreInst(cast, ci->getOperand(1), ci); GetElementPtrInst* gep = new GetElementPtrInst(ci->getOperand(1), ConstantInt::get(Type::UIntTy,1),ci->getOperand(1)->getName()+".end", @@ -1672,8 +1684,8 @@ public: return false; LoadInst* loadi = new LoadInst(ci->getOperand(1), ci->getOperand(1)->getName()+".byte",ci); - CastInst* casti = new CastInst(loadi,Type::IntTy, - loadi->getName()+".int",ci); + CastInst* casti = CastInst::createInferredCast( + loadi, Type::IntTy, loadi->getName()+".int", ci); new CallInst(fputc_func,casti,ci->getOperand(2),"",ci); break; } @@ -1726,18 +1738,16 @@ public: } // isdigit(c) -> (unsigned)c - '0' <= 9 - CastInst* cast = - new CastInst(ci->getOperand(1),Type::UIntTy, - ci->getOperand(1)->getName()+".uint",ci); + CastInst* cast = CastInst::createInferredCast(ci->getOperand(1), + Type::UIntTy, ci->getOperand(1)->getName()+".uint", ci); BinaryOperator* sub_inst = BinaryOperator::createSub(cast, ConstantInt::get(Type::UIntTy,0x30), ci->getOperand(1)->getName()+".sub",ci); SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst, ConstantInt::get(Type::UIntTy,9), ci->getOperand(1)->getName()+".cmp",ci); - CastInst* c2 = - new CastInst(setcond_inst,Type::IntTy, - ci->getOperand(1)->getName()+".isdigit",ci); + CastInst* c2 = CastInst::createInferredCast( + setcond_inst, Type::IntTy, ci->getOperand(1)->getName()+".isdigit", ci); ci->replaceAllUsesWith(c2); ci->eraseFromParent(); return true; @@ -1759,12 +1769,14 @@ public: // isascii(c) -> (unsigned)c < 128 Value *V = CI->getOperand(1); if (V->getType()->isSigned()) - V = new CastInst(V, V->getType()->getUnsignedVersion(), V->getName(), CI); + V = CastInst::createInferredCast(V, V->getType()->getUnsignedVersion(), + V->getName(), CI); Value *Cmp = BinaryOperator::createSetLT(V, ConstantInt::get(V->getType(), 128), V->getName()+".isascii", CI); if (Cmp->getType() != CI->getType()) - Cmp = new CastInst(Cmp, CI->getType(), Cmp->getName(), CI); + Cmp = CastInst::createInferredCast( + Cmp, CI->getType(), Cmp->getName(), CI); CI->replaceAllUsesWith(Cmp); CI->eraseFromParent(); return true; @@ -1858,9 +1870,10 @@ public: Function *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType, ArgType, NULL); - Value *V = new CastInst(TheCall->getOperand(1), ArgType, "tmp", TheCall); + Value *V = CastInst::createInferredCast( + TheCall->getOperand(1), ArgType, "tmp", TheCall); Value *V2 = new CallInst(F, V, "tmp", TheCall); - V2 = new CastInst(V2, Type::IntTy, "tmp", TheCall); + V2 = CastInst::createInferredCast(V2, Type::IntTy, "tmp", TheCall); V2 = BinaryOperator::createAdd(V2, ConstantInt::get(Type::IntTy, 1), "tmp", TheCall); Value *Cond = @@ -1920,7 +1933,7 @@ struct UnaryDoubleFPOptimizer : public LibCallOptimization { if (Cast->getOperand(0)->getType() == Type::FloatTy) { Value *New = new CallInst((SLC.*FP)(), Cast->getOperand(0), CI->getName(), CI); - New = new CastInst(New, Type::DoubleTy, CI->getName(), CI); + New = new FPExtInst(New, Type::DoubleTy, CI->getName(), CI); CI->replaceAllUsesWith(New); CI->eraseFromParent(); if (Cast->use_empty()) @@ -2105,7 +2118,7 @@ bool getConstantStringLength(Value *V, uint64_t &len, ConstantArray **CA) { Value *CastToCStr(Value *V, Instruction &IP) { const Type *SBPTy = PointerType::get(Type::SByteTy); if (V->getType() != SBPTy) - return new CastInst(V, SBPTy, V->getName(), &IP); + return CastInst::createInferredCast(V, SBPTy, V->getName(), &IP); return V; } diff --git a/lib/Transforms/Instrumentation/ProfilingUtils.cpp b/lib/Transforms/Instrumentation/ProfilingUtils.cpp index 4c31793f42..887de5bfe2 100644 --- a/lib/Transforms/Instrumentation/ProfilingUtils.cpp +++ b/lib/Transforms/Instrumentation/ProfilingUtils.cpp @@ -62,7 +62,8 @@ void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, case 2: AI = MainFn->arg_begin(); ++AI; if (AI->getType() != ArgVTy) { - InitCall->setOperand(2, new CastInst(AI, ArgVTy, "argv.cast", InitCall)); + InitCall->setOperand(2, + CastInst::createInferredCast(AI, ArgVTy, "argv.cast", InitCall)); } else { InitCall->setOperand(2, AI); } @@ -73,10 +74,10 @@ void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, // init call instead. if (AI->getType() != Type::IntTy) { if (!AI->use_empty()) - AI->replaceAllUsesWith(new CastInst(InitCall, AI->getType(), "", - InsertPos)); - InitCall->setOperand(1, new CastInst(AI, Type::IntTy, "argc.cast", - InitCall)); + AI->replaceAllUsesWith( + CastInst::createInferredCast(InitCall, AI->getType(), "", InsertPos)); + InitCall->setOperand(1, + CastInst::createInferredCast(AI, Type::IntTy, "argc.cast", InitCall)); } else { AI->replaceAllUsesWith(InitCall); InitCall->setOperand(1, AI); diff --git a/lib/Transforms/Instrumentation/TraceValues.cpp b/lib/Transforms/Instrumentation/TraceValues.cpp index d335f16cad..7451b51c31 100644 --- a/lib/Transforms/Instrumentation/TraceValues.cpp +++ b/lib/Transforms/Instrumentation/TraceValues.cpp @@ -190,8 +190,7 @@ static inline bool TraceThisOpCode(unsigned opCode) { // return (opCode < Instruction::OtherOpsBegin && opCode != Instruction::Alloca && - opCode != Instruction::PHI && - opCode != Instruction::Cast); + opCode != Instruction::PHI && ! Instruction::isCast(opCode)); } @@ -251,7 +250,7 @@ static void InsertPrintInst(Value *V, BasicBlock *BB, Instruction *InsertBefore, if (V && isa<PointerType>(V->getType()) && !DisablePtrHashing) { const Type *SBP = PointerType::get(Type::SByteTy); if (V->getType() != SBP) // Cast pointer to be sbyte* - V = new CastInst(V, SBP, "Hash_cast", InsertBefore); + V = new BitCastInst(V, SBP, "Hash_cast", InsertBefore); std::vector<Value*> HashArgs(1, V); V = new CallInst(HashPtrToSeqNum, HashArgs, "ptrSeqNum", InsertBefore); @@ -282,7 +281,7 @@ InsertReleaseInst(Value *V, BasicBlock *BB, const Type *SBP = PointerType::get(Type::SByteTy); if (V->getType() != SBP) // Cast pointer to be sbyte* - V = new CastInst(V, SBP, "RPSN_cast", InsertBefore); + V = CastInst::createInferredCast(V, SBP, "RPSN_cast", InsertBefore); std::vector<Value*> releaseArgs(1, V); new CallInst(ReleasePtrFunc, releaseArgs, "", InsertBefore); @@ -294,7 +293,7 @@ InsertRecordInst(Value *V, BasicBlock *BB, Function* RecordPtrFunc) { const Type *SBP = PointerType::get(Type::SByteTy); if (V->getType() != SBP) // Cast pointer to be sbyte* - V = new CastInst(V, SBP, "RP_cast", InsertBefore); + V = CastInst::createInferredCast(V, SBP, "RP_cast", InsertBefore); std::vector<Value*> releaseArgs(1, V); new CallInst(RecordPtrFunc, releaseArgs, "", InsertBefore); diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp index 7713609907..c8635e181f 100644 --- a/lib/Transforms/LevelRaise.cpp +++ b/lib/Transforms/LevelRaise.cpp @@ -87,15 +87,6 @@ FunctionPass *llvm::createRaisePointerReferencesPass() { return new RPR(); } - -// isReinterpretingCast - Return true if the cast instruction specified will -// cause the operand to be "reinterpreted". A value is reinterpreted if the -// cast instruction would cause the underlying bits to change. -// -static inline bool isReinterpretingCast(const CastInst *CI) { - return!CI->getOperand(0)->getType()->isLosslesslyConvertibleTo(CI->getType()); -} - bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { Instruction *I = BI; const TargetData &TD = getAnalysis<TargetData>(); @@ -129,7 +120,7 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { // Check to see if it's a cast of an instruction that does not depend on the // specific type of the operands to do it's job. - if (!isReinterpretingCast(CI)) { + if (CI->isLosslessCast()) { ValueTypeCache ConvertedTypes; // Check to see if we can convert the source of the cast to match the @@ -238,7 +229,7 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { Indices.push_back(Constant::getNullValue(Type::UIntTy)); // Did we find what we're looking for? - if (ElTy->isLosslesslyConvertibleTo(DestPointedTy)) break; + if (ElTy->canLosslesslyBitCastTo(DestPointedTy)) break; // Nope, go a level deeper. ++Depth; @@ -257,9 +248,23 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { Name, BI); // Make the old cast instruction reference the new GEP instead of - // the old src value. - // - CI->setOperand(0, GEP); + // the old src value. + if (CI->getOperand(0)->getType() == GEP->getType()) { + // If the source types are the same we can safely replace the + // first operand of the CastInst because the opcode won't + // change as a result. + CI->setOperand(0, GEP); + } else { + // The existing and new operand 0 types are different so we must + // replace CI with a new CastInst so that we are assured to + // get the correct cast opcode. + CastInst *NewCI = CastInst::createInferredCast( + GEP, CI->getType(), CI->getName(), CI); + CI->replaceAllUsesWith(NewCI); + CI->eraseFromParent(); + CI = NewCI; + BI = NewCI; // Don't let the iterator invalidate + } PRINT_PEEPHOLE2("cast-for-first:out", *GEP, *CI); ++NumGEPInstFormed; @@ -273,7 +278,7 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { Value *Pointer = SI->getPointerOperand(); // Peephole optimize the following instructions: - // %t = cast <T1>* %P to <T2> * ;; If T1 is losslessly convertible to T2 + // %t = cast <T1>* %P to <T2> * ;; If T1 is losslessly castable to T2 // store <T2> %V, <T2>* %t // // Into: @@ -289,13 +294,14 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType())) // convertible types? - if (Val->getType()->isLosslesslyConvertibleTo(CSPT->getElementType())) { + if (Val->getType()->canLosslesslyBitCastTo(CSPT->getElementType())) + { PRINT_PEEPHOLE3("st-src-cast:in ", *Pointer, *Val, *SI); // Insert the new T cast instruction... stealing old T's name std::string Name(CI->getName()); CI->setName(""); - CastInst *NCI = new CastInst(Val, CSPT->getElementType(), - Name, BI); + CastInst *NCI = CastInst::create(Instruction::BitCast, Val, + CSPT->getElementType(), Name, BI); // Replace the old store with a new one! ReplaceInstWithInst(BB->getInstList(), BI, @@ -327,14 +333,16 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType())) // convertible types? - if (PtrElType->isLosslesslyConvertibleTo(CSPT->getElementType())) { + if (PtrElType->canLosslesslyBitCastTo(CSPT->getElementType())) { PRINT_PEEPHOLE2("load-src-cast:in ", *Pointer, *LI); // Create the new load instruction... loading the pre-casted value LoadInst *NewLI = new LoadInst(CastSrc, LI->getName(), BI); // Insert the new T cast instruction... stealing old T's name - CastInst *NCI = new CastInst(NewLI, LI->getType(), CI->getName()); + CastInst *NCI = + CastInst::create(Instruction::BitCast, NewLI, LI->getType(), + CI->getName()); // Replace the old store with a new one! ReplaceInstWithInst(BB->getInstList(), BI, NCI); @@ -366,15 +374,12 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { // Create a new cast, inserting it right before the function call... Value *NewCast; - Constant *ConstantCallSrc = 0; if (Constant *CS = dyn_cast<Constant>(CI->getCalledValue())) - ConstantCallSrc = CS; - - if (ConstantCallSrc) - NewCast = ConstantExpr::getCast(ConstantCallSrc, NewPFunTy); + NewCast = ConstantExpr::getBitCast(CS, NewPFunTy); else - NewCast = new CastInst(CI->getCalledValue(), NewPFunTy, - CI->getCalledValue()->getName()+"_c",CI); + NewCast = CastInst::create(Instruction::BitCast, CI->getCalledValue(), + NewPFunTy, + CI->getCalledValue()->getName()+"_c", CI); // Create a new call instruction... CallInst *NewCall = new CallInst(NewCast, diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 1059159aad..cd674ae4b6 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -523,9 +523,8 @@ void IndVarSimplify::runOnLoop(Loop *L) { if (!InsertedSizes[IndVars[i].first->getType()->getPrimitiveSize()]) { PHINode *PN = IndVars[i].first; InsertedSizes[PN->getType()->getPrimitiveSize()] = true; - Instruction *New = new CastInst(IndVar, - PN->getType()->getUnsignedVersion(), - "indvar", InsertPt); + Instruction *New = CastInst::create(Instruction::Trunc, IndVar, + PN->getType()->getUnsignedVersion(), "indvar", InsertPt); Rewriter.addInsertedValue(New, SE->getSCEV(New)); } } diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 4e5d6639d4..a13b7e76ac 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -151,7 +151,20 @@ namespace { Instruction *visitShiftInst(ShiftInst &I); Instruction *FoldShiftByConstant(Value *Op0, ConstantInt *Op1, ShiftInst &I); - Instruction *visitCastInst(CastInst &CI); + Instruction *commonCastTransforms(CastInst &CI); + Instruction *commonIntCastTransforms(CastInst &CI); + Instruction *visitTrunc(CastInst &CI); + Instruction *visitZExt(CastInst &CI); + Instruction *visitSExt(CastInst &CI); + Instruction *visitFPTrunc(CastInst &CI); + Instruction *visitFPExt(CastInst &CI); + Instruction *visitFPToUI(CastInst &CI); + Instruction *visitFPToSI(CastInst &CI); + Instruction *visitUIToFP(CastInst &CI); + Instruction *visitSIToFP(CastInst &CI); + Instruction *visitPtrToInt(CastInst &CI); + Instruction *visitIntToPtr(CastInst &CI); + Instruction *visitBitCast(CastInst &CI); Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI); Instruction *visitSelectInst(SelectInst &CI); @@ -198,7 +211,7 @@ namespace { if (Constant *CV = dyn_cast<Constant>(V)) return ConstantExpr::getCast(CV, Ty); - Instruction *C = new CastInst(V, Ty, V->getName(), &Pos); + Instruction *C = CastInst::createInferredCast(V, Ty, V->getName(), &Pos); WorkList.push_back(C); return C; } @@ -329,113 +342,38 @@ static const Type *getPromotedType(const Type *Ty) { } } -/// isCast - If the specified operand is a CastInst or a constant expr cast, -/// return the operand value, otherwise return null. -static Value *isCast(Value *V) { - if (CastInst *I = dyn_cast<CastInst>(V)) +/// getBitCastOperand - If the specified operand is a CastInst or a constant +/// expression bitcast, return the operand value, otherwise return null. +static Value *getBitCastOperand(Value *V) { + if (BitCastInst *I = dyn_cast<BitCastInst>(V)) return I->getOperand(0); else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->getOpcode() == Instruction::BitCast) return CE->getOperand(0); return 0; } -enum CastType { - Noop = 0, - Truncate = 1, - Signext = 2, - Zeroext = 3 -}; - -/// getCastType - In the future, we will split the cast instruction into these -/// various types. Until then, we have to do the analysis here. -static CastType getCastType(const Type *Src, const Type *Dest) { - assert(Src->isIntegral() && Dest->isIntegral() && - "Only works on integral types!"); - unsigned SrcSize = Src->getPrimitiveSizeInBits(); - unsigned DestSize = Dest->getPrimitiveSizeInBits(); +/// This function is a wrapper around CastInst::isEliminableCastPair. It +/// simply extracts arguments and returns what that function returns. +/// @Determine if it is valid to eliminate a Convert pair +static Instruction::CastOps +isEliminableCastPair( + const CastInst *CI, ///< The first cast instruction + unsigned opcode, ///< The opcode of the second cast instruction + const Type *DstTy, ///< The target type for the second cast instruction + TargetData *TD ///< The target data for pointer size +) { - if (SrcSize == DestSize) return Noop; - if (SrcSize > DestSize) return Truncate; - if (Src->isSigned()) return Signext; - return Zeroext; -} + const Type *SrcTy = CI->getOperand(0)->getType(); // A from above + const Type *MidTy = CI->getType(); // B from above + // Get the opcodes of the two Cast instructions + Instruction::CastOps firstOp = Instruction::CastOps(CI->getOpcode()); + Instruction::CastOps secondOp = Instruction::CastOps(opcode); -// isEliminableCastOfCast - Return true if it is valid to eliminate the CI -// instruction. -// -static bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy, - const Type *DstTy, TargetData *TD) { - - // It is legal to eliminate the instruction if casting A->B->A if the sizes - // are identical and the bits don't get reinterpreted (for example - // int->float->int would not be allowed). - if (SrcTy == DstTy && SrcTy->isLosslesslyConvertibleTo(MidTy)) - return true; - - // If we are casting between pointer and integer types, treat pointers as - // integers of the appropriate size for the code below. - if (isa<PointerType>(SrcTy)) SrcTy = TD->getIntPtrType(); - if (isa<PointerType>(MidTy)) MidTy = TD->getIntPtrType(); - if (isa<PointerType>(DstTy)) DstTy = TD->getIntPtrType(); - - // Allow free casting and conversion of sizes as long as the sign doesn't - // change... - if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) { - CastType FirstCast = getCastType(SrcTy, MidTy); - CastType SecondCast = getCastType(MidTy, DstTy); - - // Capture the effect of these two casts. If the result is a legal cast, - // the CastType is stored here, otherwise a special code is used. - static const unsigned CastResult[] = { - // First cast is noop - 0, 1, 2, 3, - // First cast is a truncate - 1, 1, 4, 4, // trunc->extend is not safe to eliminate - // First cast is a sign ext - 2, 5, 2, 4, // signext->zeroext never ok - // First cast is a zero ext - 3, 5, 3, 3, - }; - - unsigned Result = CastResult[FirstCast*4+SecondCast]; - switch (Result) { - default: assert(0 && "Illegal table value!"); - case 0: - case 1: - case 2: - case 3: - // FIXME: in the future, when LLVM has explicit sign/zeroextends and - // truncates, we could eliminate more casts. - return (unsigned)getCastType(SrcTy, DstTy) == Result; - case 4: - return false; // Not possible to eliminate this here. - case 5: - // Sign or zero extend followed by truncate is always ok if the result - // is a truncate or noop. - CastType ResultCast = getCastType(SrcTy, DstTy); - if (ResultCast == Noop || ResultCast == Truncate) - return true; - // Otherwise we are still growing the value, we are only safe if the - // result will match the sign/zeroextendness of the result. - return ResultCast == FirstCast; - } - } - - // If this is a cast from 'float -> double -> integer', cast from - // 'float -> integer' directly, as the value isn't changed by the - // float->double conversion. - if (SrcTy->isFloatingPoint() && MidTy->isFloatingPoint() && - DstTy->isIntegral() && - SrcTy->getPrimitiveSize() < MidTy->getPrimitiveSize()) - return true; - - // Packed type conversions don't modify bits. - if (isa<PackedType>(SrcTy) && isa<PackedType>(MidTy) &&isa<PackedType>(DstTy)) - return true; - - return false; + return Instruction::CastOps( + CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, + DstTy, TD->getIntPtrType())); } /// ValueRequiresCast - Return true if the cast from "V to Ty" actually results @@ -445,13 +383,12 @@ static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) { if (V->getType() == Ty || isa<Constant>(V)) return false; // If this is a noop cast, it isn't real codegen. - if (V->getType()->isLosslesslyConvertibleTo(Ty)) + if (V->getType()->canLosslesslyBitCastTo(Ty)) return false; // If this is another cast that can be eliminated, it isn't codegen either. if (const CastInst *CI = dyn_cast<CastInst>(V)) - if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty, - TD)) + if (isEliminableCastPair(CI, CastInst::getCastOpcode(V, Ty), Ty, TD)) return false; return true; } @@ -672,48 +609,62 @@ static void ComputeMaskedBits(Value *V, uint64_t Mask, uint64_t &KnownZero, KnownOne &= KnownOne2; KnownZero &= KnownZero2; return; - case Instruction::Cast: { + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::SIToFP: + case Instruction::PtrToInt: + case Instruction::UIToFP: + case Instruction::IntToPtr: + return; // Can't work with floating point or pointers + case Instruction::Trunc: + // All these have integer operands + ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); + return; + case Instruction::BitCast: { const Type *SrcTy = I->getOperand(0)->getType(); - if (!SrcTy->isIntegral()) return; - - // If this is an integer truncate or noop, just look in the input. - if (SrcTy->getPrimitiveSizeInBits() >= - I->getType()->getPrimitiveSizeInBits()) { + if (SrcTy->isIntegral()) { ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); return; } - - // Sign or Zero extension. Compute the bits in the result that are not - // present in the input. + break; + } + case Instruction::ZExt: { + // Compute the bits in the result that are not present in the input. + const Type *SrcTy = I->getOperand(0)->getType(); uint64_t NotIn = ~SrcTy->getIntegralTypeMask(); uint64_t NewBits = I->getType()->getIntegralTypeMask() & NotIn; - // Handle zero extension. - if (!SrcTy->isSigned()) { - Mask &= SrcTy->getIntegralTypeMask(); - ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); - assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - // The top bits are known to be zero. - KnownZero |= NewBits; - } else { - // Sign extension. - Mask &= SrcTy->getIntegralTypeMask(); - ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); - assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + Mask &= SrcTy->getIntegralTypeMask(); + ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + // The top bits are known to be zero. + KnownZero |= NewBits; + return; + } + case Instruction::SExt: { + // Compute the bits in the result that are not present in the input. + const Type *SrcTy = I->getOperand(0)->getType(); + uint64_t NotIn = ~SrcTy->getIntegralTypeMask(); + uint64_t NewBits = I->getType()->getIntegralTypeMask() & NotIn; + + Mask &= SrcTy->getIntegralTypeMask(); + ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1); + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - // If the sign bit of the input is known set or clear, then we know the - // top bits of the result. - uint64_t InSignBit = 1ULL << (SrcTy->getPrimitiveSizeInBits()-1); - if (KnownZero & InSignBit) { // Input sign bit known zero - KnownZero |= NewBits; - KnownOne &= ~NewBits; - } else if (KnownOne & InSignBit) { // Input sign bit known set - KnownOne |= NewBits; - KnownZero &= ~NewBits; - } else { // Input sign bit unknown - KnownZero &= ~NewBits; - KnownOne &= ~NewBits; - } + // If the sign bit of the input is known set or clear, then we know the + // top bits of the result. + uint64_t InSignBit = 1ULL << (SrcTy->getPrimitiveSizeInBits()-1); + if (KnownZero & InSignBit) { // Input sign bit known zero + KnownZero |= NewBits; + KnownOne &= ~NewBits; + } else if (KnownOne & InSignBit) { // Input sign bit known set + KnownOne |= NewBits; + KnownZero &= ~NewBits; + } else { // Input sign bit unknown + KnownZero &= ~NewBits; + KnownOne &= ~NewBits; } return; } @@ -894,7 +845,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t DemandedMask, DemandedMask &= V->getType()->getIntegralTypeMask(); - uint64_t KnownZero2, KnownOne2; + uint64_t KnownZero2 = 0, KnownOne2 = 0; switch (I->getOpcode()) { default: break; case Instruction::And: @@ -911,7 +862,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t DemandedMask, return true; assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); - // If all of the demanded bits are known one on one side, return the other. + // If all of the demanded bits are known 1 on one side, return the other. // These bits cannot contribute to the result of the 'and'. if ((DemandedMask & ~KnownZero2 & KnownOne) == (DemandedMask & ~KnownZero2)) return UpdateValueUsesWith(I, I->getOperand(0)); @@ -1045,74 +996,72 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t DemandedMask, KnownOne &= KnownOne2; KnownZero &= KnownZero2; break; - case Instruction::Cast: { - const Type *SrcTy = I->getOperand(0)->getType(); - if (!SrcTy->isIntegral()) return false; - - // If this is an integer truncate or noop, just look in the input. - if (SrcTy->getPrimitiveSizeInBits() >= - I->getType()->getPrimitiveSizeInBits()) { - // Cast to bool is a comparison against 0, which demands all bits. We - // can't propagate anything useful up. - if (I->getType() == Type::BoolTy) - break; + case Instruction::Trunc: + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + KnownZero, KnownOne, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + break; + case Instruction::BitCast: + if (!I->getOperand(0)->getType()->isIntegral()) + return false; - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, - KnownZero, KnownOne, Depth+1)) - return true; - assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - break; - } + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + KnownZero, KnownOne, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + break; + case Instruction::ZExt: { + // Compute the bits in the result that are not present in the input. + const Type *SrcTy = I->getOperand(0)->getType(); + uint64_t NotIn = ~SrcTy->getIntegralTypeMask(); + uint64_t NewBits = I->getType()->getIntegralTypeMask() & NotIn; - // Sign or Zero extension. Compute the bits in the result that are not - // present in the input. + DemandedMask &= SrcTy->getIntegralTypeMask(); + if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + KnownZero, KnownOne, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + // The top bits are known to be zero. + KnownZero |= NewBits; + break; + } + case Instruction::SExt: { + // Compute the bits in the result that are not present in the input. + const Type *SrcTy = I->getOperand(0)->getType(); uint64_t NotIn = ~SrcTy->getIntegralTypeMask(); uint64_t NewBits = I->getType()->getIntegralTypeMask() & NotIn; - // Handle zero extension. - if (!SrcTy->isSigned()) { - DemandedMask &= SrcTy->getIntegralTypeMask(); - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, - KnownZero, KnownOne, Depth+1)) - return true; - assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - // The top bits are known to be zero. - KnownZero |= NewBits; - } else { - // Sign extension. - uint64_t InSignBit = 1ULL << (SrcTy->getPrimitiveSizeInBits()-1); - int64_t InputDemandedBits = DemandedMask & SrcTy->getIntegralTypeMask(); - - // If any of the sign extended bits are demanded, we know that the sign - // bit is demanded. - if (NewBits & DemandedMask) - InputDemandedBits |= InSignBit; + // Get the sign bit for the source type + uint64_t InSignBit = 1ULL << (SrcTy->getPrimitiveSizeInBits()-1); + int64_t InputDemandedBits = DemandedMask & SrcTy->getIntegralTypeMask(); + + // If any of the sign extended bits are demanded, we know that the sign + // bit is demanded. + if (NewBits & DemandedMask) + InputDemandedBits |= InSignBit; - if (SimplifyDemandedBits(I->getOperand(0), InputDemandedBits, - KnownZero, KnownOne, Depth+1)) - return true; - assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); + if (SimplifyDemandedBits(I->getOperand(0), InputDemandedBits, + KnownZero, KnownOne, Depth+1)) + return true; + assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - // If the sign bit of the input is known set or clear, then we know the - // top bits of the result. - - // If the input sign bit is known zero, or if the NewBits are not demanded - // convert this into a zero extension. - if ((KnownZero & InSignBit) || (NewBits & ~DemandedMask) == NewBits) { - // Convert to unsigned first. - Value *NewVal = - InsertCastBefore(I->getOperand(0), SrcTy->getUnsignedVersion(), *I); - // Then cast that to the destination type. - NewVal = new CastInst(NewVal, I->getType(), I->getName()); - InsertNewInstBefore(cast<Instruction>(NewVal), *I); - return UpdateValueUsesWith(I, NewVal); - } else if (KnownOne & InSignBit) { // Input sign bit known set - KnownOne |= NewBits; - KnownZero &= ~NewBits; - } else { // Input sign bit unknown - KnownZero &= ~NewBits; - KnownOne &= ~NewBits; - } + // If the sign bit of the input is known set or clear, then we know the + // top bits of the result. + + // If the input sign bit is known zero, or if the NewBits are not demanded + // convert this into a zero extension. + if ((KnownZero & InSignBit) || (NewBits & ~DemandedMask) == NewBits) { + // Convert to ZExt cast + CastInst *NewCast = CastInst::create( + Instruction::ZExt, I->getOperand(0), I->getType(), I->getName(), I); + return UpdateValueUsesWith(I, NewCast); + } else if (KnownOne & InSignBit) { // Input sign bit known set + KnownOne |= NewBits; + KnownZero &= ~NewBits; + } else { // Input sign bit unknown + KnownZero &= ~NewBits; + KnownOne &= ~NewBits; } break; } @@ -1618,12 +1567,12 @@ struct AddMaskingAnd { static Value *FoldOperationIntoSelectOperand(Instruction &I, Value *SO, InstCombiner *IC) { - if (isa<CastInst>(I)) { + if (CastInst *CI = dyn_cast<CastInst>(&I)) { if (Constant *SOC = dyn_cast<Constant>(SO)) - return ConstantExpr::getCast(SOC, I.getType()); + return ConstantExpr::getCast(CI->getOpcode(), SOC, I.getType()); - return IC->InsertNewInstBefore(new CastInst(SO, I.getType(), - SO->getName() + ".cast"), I); + return IC->InsertNewInstBefore(CastInst::create( + CI->getOpcode(), SO, I.getType(), SO->getName() + ".cast"), I); } // Figure out if the constant is the left or the right argument. @@ -1738,17 +1687,18 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) { } NewPN->addIncoming(InV, PN->getIncomingBlock(i)); } - } else { - assert(isa<CastInst>(I) && "Unary op should be a cast!"); - const Type *RetTy = I.getType(); + } else { + CastInst *CI = cast<CastInst>(&I); + const Type *RetTy = CI->getType(); for (unsigned i = 0; i != NumPHIValues; ++i) { Value *InV; if (Constant *InC = dyn_cast<Constant>(PN->getIncomingValue(i))) { - InV = ConstantExpr::getCast(InC, RetTy); + InV = ConstantExpr::getCast(CI->getOpcode(), InC, RetTy); } else { assert(PN->getIncomingBlock(i) == NonConstBB); - InV = new CastInst(PN->getIncomingValue(i), I.getType(), "phitmp", - NonConstBB->getTerminator()); + InV = CastInst::create(CI->getOpcode(), PN->getIncomingValue(i), + I.getType(), "phitmp", + NonConstBB->getTerminator()); WorkList.push_back(cast<Instruction>(InV)); } NewPN->addIncoming(InV, PN->getIncomingBlock(i)); @@ -1840,9 +1790,10 @@ FoundSExt: case 8: MiddleType = Type::SByteTy; break; } if (MiddleType) { - Instruction *NewTrunc = new CastInst(XorLHS, MiddleType, "sext"); + Instruction *NewTrunc = + CastInst::createInferredCast(XorLHS, MiddleType, "sext"); InsertNewInstBefore(NewTrunc, I); - return new CastInst(NewTrunc, I.getType()); + return new SExtInst(NewTrunc, I.getType()); } } } @@ -1934,8 +1885,8 @@ FoundSExt: // cast (GEP (cast *A to sbyte*) B) -> // intptrtype { - CastInst* CI = dyn_cast<CastInst>(LHS); - Value* Other = RHS; + CastInst *CI = dyn_cast<CastInst>(LHS); + Value *Other = RHS; if (!CI) { CI = dyn_cast<CastInst>(RHS); Other = LHS; @@ -1944,10 +1895,10 @@ FoundSExt: (CI->getType()->getPrimitiveSize() == TD->getIntPtrType()->getPrimitiveSize()) && isa<PointerType>(CI->getOperand(0)->getType())) { - Value* I2 = InsertCastBefore(CI->getOperand(0), + Value *I2 = InsertCastBefore(CI->getOperand(0), PointerType::get(Type::SByteTy), I); I2 = InsertNewInstBefore(new GetElementPtrInst(I2, Other, "ctg2"), I); - return new CastInst(I2, CI->getType()); + return new PtrToIntInst(I2, CI->getType()); } } @@ -2266,7 +2217,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { /// regardless of the kind of div instruction it is (udiv, sdiv, or fdiv). It is /// used by the visitors to those instructions. /// @brief Transforms common to all three div instructions -Instruction* InstCombiner::commonDivTransforms(BinaryOperator &I) { +Instruction *InstCombiner::commonDivTransforms(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); // undef / X -> 0 @@ -2317,7 +2268,7 @@ Instruction* InstCombiner::commonDivTransforms(BinaryOperator &I) { /// instructions (udiv and sdiv). It is called by the visitors to those integer /// division instructions. /// @brief Common integer divide transforms -Instruction* InstCombiner::commonIDivTransforms(BinaryOperator &I) { +Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (Instruction *Common = commonDivTransforms(I)) @@ -2380,7 +2331,7 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) { uint64_t C1 = cast<ConstantInt>(RHSI->getOperand(0))->getZExtValue(); if (isPowerOf2_64(C1)) { Value *N = RHSI->getOperand(1); - const Type* NTy = N->getType(); + const Type *NTy = N->getType(); if (uint64_t C2 = Log2_64(C1)) { Constant *C2V = ConstantInt::get(NTy, C2); N = InsertNewInstBefore(BinaryOperator::createAdd(N, C2V, "tmp"), I); @@ -2483,11 +2434,12 @@ static Constant *GetFactor(Value *V) { return ConstantExpr::getShl(Result, ConstantInt::get(Type::UByteTy, Zeros)); } - } else if (I->getOpcode() == Instruction::Cast) { - Value *Op = I->getOperand(0); + } else if (CastInst *CI = dyn_cast<CastInst>(I)) { // Only handle int->int casts. - if (!Op->getType()->isInteger()) return Result; - return ConstantExpr::getCast(GetFactor(Op), V->getType()); + if (!CI->isIntegerCast()) + return Result; + Value *Op = CI->getOperand(0); + return ConstantExpr::getCast(CI->getOpcode(), GetFactor(Op), V->getType()); } return Result; } @@ -3123,33 +3075,34 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (Instruction *Res = OptAndOp(Op0I, Op0CI, AndRHS, I)) return Res; } else if (CastInst *CI = dyn_cast<CastInst>(Op0)) { - const Type *SrcTy = CI->getOperand(0)->getType(); - // If this is an integer truncation or change from signed-to-unsigned, and // if the source is an and/or with immediate, transform it. This // frequently occurs for bitfield accesses. if (Instruction *CastOp = dyn_cast<Instruction>(CI->getOperand(0))) { - if (SrcTy->getPrimitiveSizeInBits() >= - I.getType()->getPrimitiveSizeInBits() && + if ((isa<TruncInst>(CI) || isa<BitCastInst>(CI)) && CastOp->getNumOperands() == 2) if (ConstantInt *AndCI = dyn_cast<ConstantInt>(CastOp->getOperand(1))) if (CastOp->getOpcode() == Instruction::And) { // Change: and (cast (and X, C1) to T), C2 - // into : and (cast X to T), trunc(C1)&C2 - // This will folds the two ands together, which may allow other - // simplifications. + // into : and (cast X to T), trunc_or_bitcast(C1)&C2 + // This will fold the two constants together, which may allow + // other simplifications. Instruction *NewCast = - new CastInst(CastOp->getOperand(0), I.getType(), + CastInst::createInferredCast(CastOp->getOperand(0), I.getType(), CastOp->getName()+".shrunk"); NewCast = InsertNewInstBefore(NewCast, I); - - Constant *C3=ConstantExpr::getCast(AndCI, I.getType());//trunc(C1) - C3 = ConstantExpr::getAnd(C3, AndRHS); // trunc(C1)&C2 + // trunc_or_bitcast(C1)&C2 + Instruction::CastOps opc = ( + AndCI->getType()->getPrimitiveSizeInBits() == + I.getType()->getPrimitiveSizeInBits() ? + Instruction::BitCast : Instruction::Trunc); + Constant *C3 = ConstantExpr::getCast(opc, AndCI, I.getType()); + C3 = ConstantExpr::getAnd(C3, AndRHS); return BinaryOperator::createAnd(NewCast, C3); } else if (CastOp->getOpcode() == Instruction::Or) { // Change: and (cast (or X, C1) to T), C2 // into : trunc(C1)&C2 iff trunc(C1)&C2 == C2 - Constant *C3=ConstantExpr::getCast(AndCI, I.getType());//trunc(C1) + Constant *C3 = ConstantExpr::getCast(AndCI, I.getType()); if (ConstantExpr::getAnd(C3, AndRHS) == AndRHS) // trunc(C1)&C2 return ReplaceInstUsesWith(I, AndRHS); } @@ -3322,7 +3275,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { Op1C->getOperand(0), I.getName()); InsertNewInstBefore(NewOp, I); - return new CastInst(NewOp, I.getType()); + return CastInst::createInferredCast(NewOp, I.getType()); } } } @@ -3725,7 +3678,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { Op1C->getOperand(0), I.getName()); InsertNewInstBefore(NewOp, I); - return new CastInst(NewOp, I.getType()); + return CastInst::createInferredCast(NewOp, I.getType()); } } @@ -3906,7 +3859,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { Op1C->getOperand(0), I.getName()); InsertNewInstBefore(NewOp, I); - return new CastInst(NewOp, I.getType()); + return CastInst::createInferredCast(NewOp, I.getType()); } } @@ -3982,7 +3935,7 @@ static Value *EmitGEPOffset(User *GEP, Instruction &I, InstCombiner &IC) { } } else { // Convert to correct type. - Op = IC.InsertNewInstBefore(new CastInst(Op, SIntPtrTy, + Op = IC.InsertNewInstBefore(CastInst::createInferredCast(Op, SIntPtrTy, Op->getName()+".c"), I); if (Size != 1) // We'll let instcombine(mul) convert this to a shl if possible. @@ -4344,7 +4297,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { // have its sign bit set or if it is an equality comparison. // Extending a relational comparison when we're checking the sign // bit would not work. - if (Cast->hasOneUse() && Cast->isTruncIntCast() && + if (Cast->hasOneUse() && isa<TruncInst>(Cast) && (I.isEquality() || (AndCST->getZExtValue() == (uint64_t)AndCST->getSExtValue()) && (CI->getZExtValue() == (uint64_t)CI->getSExtValue()))) { @@ -4604,7 +4557,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { // (x /u C1) <u C2. Simply casting the operands and result won't // work. :( The if statement below tests that condition and bails // if it finds it. - const Type* DivRHSTy = DivRHS->getType(); + const Type *DivRHSTy = DivRHS->getType(); unsigned DivOpCode = LHSI->getOpcode(); if (I.isEquality() && ((DivOpCode == Instruction::SDiv && DivRHSTy->isUnsigned()) || @@ -4936,18 +4889,19 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { // values. If the cast can be stripped off both arguments, we do so now. if (CastInst *CI = dyn_cast<CastInst>(Op0)) { Value *CastOp0 = CI->getOperand(0); - if (CastOp0->getType()->isLosslesslyConvertibleTo(CI->getType()) && - (isa<Constant>(Op1) || isa<CastInst>(Op1)) && I.isEquality()) { + if (CI->isLosslessCast() && I.isEquality() && + (isa<Constant>(Op1) || isa<CastInst>(Op1))) { // We keep moving the cast from the left operand over to the right // operand, where it can often be eliminated completely. Op0 = CastOp0; // If operand #1 is a cast instruction, see if we can eliminate it as // well. - if (CastInst *CI2 = dyn_cast<CastInst>(Op1)) - if (CI2->getOperand(0)->getType()->isLosslesslyConvertibleTo( - Op0->getType())) - Op1 = CI2->getOperand(0); + if (CastInst *CI2 = dyn_cast<CastInst>(Op1)) { + Value *CI2Op0 = CI2->getOperand(0); + if (CI2Op0->getType()->canLosslesslyBitCastTo(Op0->getType())) + Op1 = CI2Op0; + } // If Op1 is a constant, we can fold the cast into the constant. if (Op1->getType() != Op0->getType()) @@ -5028,9 +4982,10 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { // We only handle extending casts so far. // Instruction *InstCombiner::visitSetCondInstWithCastAndCast(SetCondInst &SCI) { - Value *LHSCIOp = cast<CastInst>(SCI.getOperand(0))->getOperand(0); - const Type *SrcTy = LHSCIOp->getType(); - const Type *DestTy = SCI.getOperand(0)->getType(); + const CastInst *LHSCI = cast<CastInst>(SCI.getOperand(0)); + Value *LHSCIOp = LHSCI->getOperand(0); + const Type *SrcTy = LHSCIOp->getType(); + const Type *DestTy = SCI.getOperand(0)->getType(); Value *RHSCIOp; if (!DestTy->isIntegral() || !SrcTy->isIntegral()) @@ -5051,9 +5006,10 @@ Instruction *InstCombiner::visitSetCondInstWithCastAndCast(SetCondInst &SCI) { } else if (ConstantInt *CI = dyn_cast<ConstantInt>(SCI.getOperand(1))) { // Compute the constant that would happen if we truncated to SrcTy then // reextended to DestTy. - Constant *Res = ConstantExpr::getCast(CI, SrcTy); + Constant *Res1 = ConstantExpr::getTrunc(CI, SrcTy); + Constant *Res2 = ConstantExpr::getCast(LHSCI->getOpcode(), Res1, DestTy); - if (ConstantExpr::getCast(Res, DestTy) == CI) { + if (Res2 == CI) { // Make sure that src sign and dest sign match. For example, // // %A = cast short %X to uint @@ -5067,7 +5023,7 @@ Instruction *InstCombiner::visitSetCondInstWithCastAndCast(SetCondInst &SCI) { // However, it is OK if SrcTy is bool (See cast-set.ll testcase) // OR operation is EQ/NE. if (isSignSrc == isSignDest || SrcTy == Type::BoolTy || SCI.isEquality()) - RHSCIOp = Res; + RHSCIOp = Res1; else return 0; } else { @@ -5361,12 +5317,9 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1, ShiftInst *ShiftOp = 0; if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0)) ShiftOp = Op0SI; - else if (CastInst *CI = dyn_cast<CastInst>(Op0)) { - // If this is a noop-integer case of a shift instruction, use the shift. - if (CI->getOperand(0)->getType()->isInteger() && - CI->getOperand(0)->getType()->getPrimitiveSizeInBits() == - CI->getType()->getPrimitiveSizeInBits() && - isa<ShiftInst>(CI->getOperand(0))) { + else if (BitCastInst *CI = dyn_cast<BitCastInst>(Op0)) { + // If this is a noop-integer cast of a shift instruction, use the shift. + if (isa<ShiftInst>(CI->getOperand(0))) { ShiftOp = cast<ShiftInst>(CI->getOperand(0)); } } @@ -5400,13 +5353,14 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1, Value *Op = ShiftOp->getOperand(0); if (isShiftOfSignedShift != isSignedShift) - Op = InsertNewInstBefore(new CastInst(Op, I.getType(), "tmp"), I); - ShiftInst* ShiftResult = new ShiftInst(I.getOpcode(), Op, + Op = InsertNewInstBefore( + CastInst::createInferredCast(Op, I.getType(), "tmp"), I); + ShiftInst *ShiftResult = new ShiftInst(I.getOpcode(), Op, ConstantInt::get(Type::UByteTy, Amt)); if (I.getType() == ShiftResult->getType()) return ShiftResult; InsertNewInstBefore(ShiftResult, I); - return new CastInst(ShiftResult, I.getType()); + return CastInst::create(Instruction::BitCast, ShiftResult, I.getType()); } // Check for (A << c1) >> c2 or (A >> c1) << c2. If we are dealing with @@ -5454,7 +5408,7 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1, C = ConstantExpr::getShl(C, Op1); Mask = BinaryOperator::createAnd(Shift, C, Op->getName()+".mask"); InsertNewInstBefore(Mask, I); - return new CastInst(Mask, I.getType()); + return CastInst::create(Instruction::BitCast, Mask, I.getType()); } } else { // We can handle signed (X << C1) >>s C2 if it's a sign extend. In @@ -5468,10 +5422,10 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1, } if (SExtType) { - Instruction *NewTrunc = new CastInst(ShiftOp->getOperand(0), - SExtType, "sext"); + Instruction *NewTrunc = + new TruncInst(ShiftOp->getOperand(0), SExtType, "sext"); InsertNewInstBefore(NewTrunc, I); - return new CastInst(NewTrunc, I.getType()); + return new SExtInst(NewTrunc, I.getType()); } } } @@ -5622,7 +5576,9 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI, // die soon. if (!AI.hasOneUse()) { AddUsesToWorkList(AI); - CastInst *NewCast = new CastInst(New, AI.getType(), "tmpcast"); + // New is the allocation instruction, pointer typed. AI is the original + // allocation instruction, also pointer typed. Thus, cast to use is BitCast. + CastInst *NewCast = new BitCastInst(New, AI.getType(), "tmpcast"); InsertNewInstBefore(NewCast, AI); AI.replaceAllUsesWith(NewCast); } @@ -5647,7 +5603,10 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty, // These operators can all arbitrarily be extended or truncated. return CanEvaluateInDifferentType(I->getOperand(0), Ty, NumCastsRemoved) && CanEvaluateInDifferentType(I->getOperand(1), Ty, NumCastsRemoved); - case Instruction::Cast: + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::BitCast: // If this is a cast from the destination type, we can trivially eliminate // it, and this will remove a cast overall. if (I->getOperand(0)->getType() == Ty) { @@ -5660,6 +5619,8 @@ static bool CanEvaluateInDifferentType(Value *V, const Type *Ty, ++NumCastsRemoved; return true; } + break; + default: // TODO: Can handle more cases here. break; } @@ -5687,11 +5648,18 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type *Ty) { LHS, RHS, I->getName()); break; } - case Instruction::Cast: - // If this is a cast from the destination type, return the input. + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::BitCast: + // If the source type of the cast is the type we're trying for then we can + // just return the source. There's no need to insert it because its not new. if (I->getOperand(0)->getType() == Ty) return I->getOperand(0); + // Some other kind of cast, which shouldn't happen, so just .. + // FALL THROUGH + default: // TODO: Can handle more cases here. assert(0 && "Unreachable!"); break; @@ -5700,73 +5668,26 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type *Ty) { return InsertNewInstBefore(Res, *I); } - -// CastInst simplification -// -Instruction *InstCombiner::visitCastInst(CastInst &CI) { +/// @brief Implement the transforms common to all CastInst visitors. +Instruction *InstCombiner::commonCastTransforms(CastInst &CI) { Value *Src = CI.getOperand(0); - // If the user is casting a value to the same type, eliminate this cast - // instruction... - if (CI.getType() == Src->getType()) - return ReplaceInstUsesWith(CI, Src); - + // Casting undef to anything results in undef so might as just replace it and + // get rid of the cast. if (isa<UndefValue>(Src)) // cast undef -> undef return ReplaceInstUsesWith(CI, UndefValue::get(CI.getType())); - // If casting the result of another cast instruction, try to eliminate this - // one! - // + // Many cases of "cast of a cast" are eliminable. If its eliminable we just + // eliminate it now. if (CastInst *CSrc = dyn_cast<CastInst>(Src)) { // A->B->C cast - Value *A = CSrc->getOperand(0); - if (isEliminableCastOfCast(A->getType(), CSrc->getType(), - CI.getType(), TD)) { - // This instruction now refers directly to the cast's src operand. This - // has a good chance of making CSrc dead. - CI.setOperand(0, CSrc->getOperand(0)); - return &CI; - } - - // If this is an A->B->A cast, and we are dealing with integral types, try - // to convert this into a logical 'and' instruction. - // - if (A->getType()->isInteger() && - CI.getType()->isInteger() && CSrc->getType()->isInteger() && - CSrc->getType()->isUnsigned() && // B->A cast must zero extend - CSrc->getType()->getPrimitiveSizeInBits() < - CI.getType()->getPrimitiveSizeInBits()&& - A->getType()->getPrimitiveSizeInBits() == - CI.getType()->getPrimitiveSizeInBits()) { - assert(CSrc->getType() != Type::ULongTy && - "Cannot have type bigger than ulong!"); - uint64_t AndValue = CSrc->getType()->getIntegralTypeMask(); - Constant *AndOp = ConstantInt::get(A->getType()->getUnsignedVersion(), - AndValue); - AndOp = ConstantExpr::getCast(AndOp, A->getType()); - Instruction *And = BinaryOperator::createAnd(CSrc->getOperand(0), AndOp); - if (And->getType() != CI.getType()) { - And->setName(CSrc->getName()+".mask"); - InsertNewInstBefore(And, CI); - And = new CastInst(And, CI.getType()); - } - return And; + if (Instruction::CastOps opc = + isEliminableCastPair(CSrc, CI.getOpcode(), CI.getType(), TD)) { + // The first cast (CSrc) is eliminable so we need to fix up or replace + // the second cast (CI). CSrc will then have a good chance of being dead. + return CastInst::create(opc, CSrc->getOperand(0), CI.getType()); } } - - // If this is a cast to bool, turn it into the appropriate setne instruction. - if (CI.getType() == Type::BoolTy) - return BinaryOperator::createSetNE(CI.getOperand(0), - Constant::getNullValue(CI.getOperand(0)->getType())); - // See if we can simplify any instructions used by the LHS whose sole - // purpose is to compute bits we don't care about. - if (CI.getType()->isInteger() && CI.getOperand(0)->getType()->isIntegral()) { - uint64_t KnownZero, KnownOne; - if (SimplifyDemandedBits(&CI, CI.getType()->getIntegralTypeMask(), - KnownZero, KnownOne)) - return &CI; - } - // If casting the result of a getelementptr instruction with no offset, turn // this into a cast of the original pointer! // @@ -5779,6 +5700,9 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { break; } if (AllZeroOperands) { + // Changing the cast operand is usually not a good idea but it is safe + // here because the pointer operand is being replaced with another + // pointer operand so the opcode doesn't need to change. CI.setOperand(0, GEP->getOperand(0)); return &CI; } @@ -5786,268 +5710,449 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { // If we are casting a malloc or alloca to a pointer to a type of the same // size, rewrite the allocation instruction to allocate the "right" type. - // if (AllocationInst *AI = dyn_cast<AllocationInst>(Src)) if (Instruction *V = PromoteCastOfAllocation(CI, *AI)) return V; + // If we are casting a select then fold the cast into the select if (SelectInst *SI = dyn_cast<SelectInst>(Src)) if (Instruction *NV = FoldOpIntoSelect(CI, SI, this)) return NV; + + // If we are casting a PHI then fold the cast into the PHI if (isa<PHINode>(Src)) if (Instruction *NV = FoldOpIntoPhi(CI)) return NV; - // If the source and destination are pointers, and this cast is equivalent to - // a getelementptr X, 0, 0, 0... turn it into the appropriate getelementptr. - // This can enhance SROA and other transforms that want type-safe pointers. - if (const PointerType *DstPTy = dyn_cast<PointerType>(CI.getType())) - if (const PointerType *SrcPTy = dyn_cast<PointerType>(Src->getType())) { - const Type *DstTy = DstPTy->getElementType(); - const Type *SrcTy = SrcPTy->getElementType(); - - Constant *ZeroUInt = Constant::getNullValue(Type::UIntTy); - unsigned NumZeros = 0; - while (SrcTy != DstTy && - isa<CompositeType>(SrcTy) && !isa<PointerType>(SrcTy) && - SrcTy->getNumContainedTypes() /* not "{}" */) { - SrcTy = cast<CompositeType>(SrcTy)->getTypeAtIndex(ZeroUInt); - ++NumZeros; - } + return 0; +} - // If we found a path from the src to dest, create the getelementptr now. - if (SrcTy == DstTy) { - std::vector<Value*> Idxs(NumZeros+1, ZeroUInt); - return new GetElementPtrInst(Src, Idxs); - } - } - - // If the source value is an instruction with only this use, we can attempt to - // propagate the cast into the instruction. Also, only handle integral types - // for now. - if (Instruction *SrcI = dyn_cast<Instruction>(Src)) { - if (SrcI->hasOneUse() && Src->getType()->isIntegral() && - CI.getType()->isInteger()) { // Don't mess with casts to bool here - - int NumCastsRemoved = 0; - if (CanEvaluateInDifferentType(SrcI, CI.getType(), NumCastsRemoved)) { - // If this cast is a truncate, evaluting in a different type always - // eliminates the cast, so it is always a win. If this is a noop-cast - // this just removes a noop cast which isn't pointful, but simplifies - // the code. If this is a zero-extension, we need to do an AND to - // maintain the clear top-part of the computation, so we require that - // the input have eliminated at least one cast. If this is a sign - // extension, we insert two new casts (to do the extension) so we - // require that two casts have been eliminated. - bool DoXForm; - switch (getCastType(Src->getType(), CI.getType())) { - default: assert(0 && "Unknown cast type!"); - case Noop: - case Truncate: +/// Only the TRUNC, ZEXT, SEXT, and BITCONVERT can have both operands as +/// integers. This function implements the common transforms for all those +/// cases. +/// @brief Implement the transforms common to CastInst with integer operands +Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { + if (Instruction *Result = commonCastTransforms(CI)) + return Result; + + Value *Src = CI.getOperand(0); + const Type *SrcTy = Src->getType(); + const Type *DestTy = CI.getType(); + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + // FIXME. We currently implement cast-to-bool as a setne %X, 0. This is + // because codegen cannot accurately perform a truncate to bool operation. + // Something goes wrong in promotion to a larger type. When CodeGen can + // handle a proper truncation to bool, this should be removed. + if (DestTy == Type::BoolTy) + return BinaryOperator::createSetNE(Src, Constant::getNullValue(SrcTy)); + + // See if we can simplify any instructions used by the LHS whose sole + // purpose is to compute bits we don't care about. + uint64_t KnownZero = 0, KnownOne = 0; + if (SimplifyDemandedBits(&CI, DestTy->getIntegralTypeMask(), + KnownZero, KnownOne)) + return &CI; + + // If the source isn't an instruction or has more than one use then we + // can't do anything more. + if (!isa<Instruction>(Src) || !Src->hasOneUse()) + return 0; + + // Attempt to propagate the cast into the instruction. + Instruction *SrcI = cast<Instruction>(Src); + int NumCastsRemoved = 0; + if (CanEvaluateInDifferentType(SrcI, DestTy, NumCastsRemoved)) { + // If this cast is a truncate, evaluting in a different type always + // eliminates the cast, so it is always a win. If this is a noop-cast + // this just removes a noop cast which isn't pointful, but simplifies + // the code. If this is a zero-extension, we need to do an AND to + // maintain the clear top-part of the computation, so we require that + // the input have eliminated at least one cast. If this is a sign + // extension, we insert two new casts (to do the extension) so we + // require that two casts have been eliminated. + bool DoXForm = CI.isNoopCast(TD->getIntPtrType()); + if (!DoXForm) { + switch (CI.getOpcode()) { + case Instruction::Trunc: DoXForm = true; break; - case Zeroext: + case Instruction::ZExt: DoXForm = NumCastsRemoved >= 1; break; - case Signext: + case Instruction::SExt: DoXForm = NumCastsRemoved >= 2; break; + case Instruction::BitCast: + DoXForm = false; + break; + default: + // All the others use floating point so we shouldn't actually + // get here because of the check above. + assert(!"Unknown cast type .. unreachable"); + break; + } + } + + if (DoXForm) { + Value *Res = EvaluateInDifferentType(SrcI, DestTy); + assert(Res->getType() == DestTy); + switch (CI.getOpcode()) { + default: assert(0 && "Unknown cast type!"); + case Instruction::Trunc: + case Instruction::BitCast: + // Just replace this cast with the result. + return ReplaceInstUsesWith(CI, Res); + case Instruction::ZExt: { + // We need to emit an AND to clear the high bits. + assert(SrcBitSize < DestBitSize && "Not a zext?"); + Constant *C = + ConstantInt::get(Type::ULongTy, (1ULL << SrcBitSize)-1); + if (DestBitSize < 64) + C = ConstantExpr::getTrunc(C, DestTy); + else { + assert(DestBitSize == 64); + C = ConstantExpr::getBitCast(C, DestTy); } + return BinaryOperator::createAnd(Res, C); + } + case Instruction::SExt: + // We need to emit a cast to truncate, then a cast to sext. + return CastInst::create(Instruction::SExt, + InsertCastBefore(Res, Src->getType(), CI), DestTy); + } + } + } + + Value *Op0 = SrcI->getNumOperands() > 0 ? SrcI->getOperand(0) : 0; + Value *Op1 = SrcI->getNumOperands() > 1 ? SrcI->getOperand(1) : 0; + + switch (SrcI->getOpcode()) { + case Instruction::Add: + case Instruction::Mul: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + // If we are discarding information, or just changing the sign, + // rewrite. + if (DestBitSize <= SrcBitSize && DestBitSize != 1) { + // Don't insert two casts if they cannot be eliminated. We allow + // two casts to be inserted if the sizes are the same. This could + // only be converting signedness, which is a noop. + if (DestBitSize == SrcBitSize || + !ValueRequiresCast(Op1, DestTy,TD) || + !ValueRequiresCast(Op0, DestTy, TD)) { + Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); + Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI); + return BinaryOperator::create(cast<BinaryOperator>(SrcI) + ->getOpcode(), Op0c, Op1c); + } + } + + // cast (xor bool X, true) to int --> xor (cast bool X to int), 1 + if (isa<ZExtInst>(CI) && SrcBitSize == 1 && + SrcI->getOpcode() == Instruction::Xor && + Op1 == ConstantBool::getTrue() && + (!Op0->hasOneUse() || !isa<SetCondInst>(Op0))) { + Value *New = InsertOperandCastBefore(Op0, DestTy, &CI); + return BinaryOperator::createXor(New, ConstantInt::get(CI.getType(), 1)); + } + break; + case Instruction::SDiv: + case Instruction::UDiv: + case Instruction::SRem: + case Instruction::URem: + // If we are just changing the sign, rewrite. + if (DestBitSize == SrcBitSize) { + // Don't insert two casts if they cannot be eliminated. We allow + // two casts to be inserted if the sizes are the same. This could + // only be converting signedness, which is a noop. + if (!ValueRequiresCast(Op1, DestTy,TD) || + !ValueRequiresCast(Op0, DestTy, TD)) { + Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); + Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI); + return BinaryOperator::create( + cast<BinaryOperator>(SrcI)->getOpcode(), Op0c, Op1c); + } + } + break; + + case Instruction::Shl: + // Allow changing the sign of the source operand. Do not allow + // changing the size of the shift, UNLESS the shift amount is a + // constant. We must not change variable sized shifts to a smaller + // size, because it is undefined to shift more bits out than exist + // in the value. + if (DestBitSize == SrcBitSize || + (DestBitSize < SrcBitSize && isa<Constant>(Op1))) { + Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); + return new ShiftInst(Instruction::Shl, Op0c, Op1); + } + break; + case Instruction::AShr: + // If this is a signed shr, and if all bits shifted in are about to be + // truncated off, turn it into an unsigned shr to allow greater + // simplifications. + if (DestBitSize < SrcBitSize && + isa<ConstantInt>(Op1)) { + unsigned ShiftAmt = cast<ConstantInt>(Op1)->getZExtValue(); + if (SrcBitSize > ShiftAmt && SrcBitSize-ShiftAmt >= DestBitSize) { + // Insert the new logical shift right. + return new ShiftInst(Instruction::LShr, Op0, Op1); + } + } + break; + + case Instruction::SetEQ: + case Instruction::SetNE: + // If we are just checking for a seteq of a single bit and casting it + // to an integer. If so, shift the bit to the appropriate place then + // cast to integer to avoid the comparison. + if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { + uint64_t Op1CV = Op1C->getZExtValue(); + // cast (X == 0) to int --> X^1 iff X has only the low bit set. + // cast (X == 0) to int --> (X>>1)^1 iff X has only the 2nd bit set. + // cast (X == 1) to int --> X iff X has only the low bit set. + // cast (X == 2) to int --> X>>1 iff X has only the 2nd bit set. + // cast (X != 0) to int --> X iff X has only the low bit set. + // cast (X != 0) to int --> X>>1 iff X has only the 2nd bit set. + // cast (X != 1) to int --> X^1 iff X has only the low bit set. + // cast (X != 2) to int --> (X>>1)^1 iff X has only the 2nd bit set. + if (Op1CV == 0 || isPowerOf2_64(Op1CV)) { + // If Op1C some other power of two, convert: + uint64_t KnownZero, KnownOne; + uint64_t TypeMask = Op1->getType()->getIntegralTypeMask(); + ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); - if (DoXForm) { - Value *Res = EvaluateInDifferentType(SrcI, CI.getType()); - assert(Res->getType() == CI.getType()); - switch (getCastType(Src->getType(), CI.getType())) { - default: assert(0 && "Unknown cast type!"); - case Noop: - case Truncate: - // Just replace this cast with the result. + if (isPowerOf2_64(KnownZero^TypeMask)) { // Exactly 1 possible 1? + bool isSetNE = SrcI->getOpcode() == Instruction::SetNE; + if (Op1CV && (Op1CV != (KnownZero^TypeMask))) { + // (X&4) == 2 --> false + // (X&4) != 2 --> true + Constant *Res = ConstantBool::get(isSetNE); + Res = ConstantExpr::getZeroExtend(Res, CI.getType()); return ReplaceInstUsesWith(CI, Res); - case Zeroext: { - // We need to emit an AND to clear the high bits. - unsigned SrcBitSize = Src->getType()->getPrimitiveSizeInBits(); - unsigned DestBitSize = CI.getType()->getPrimitiveSizeInBits(); - assert(SrcBitSize < DestBitSize && "Not a zext?"); - Constant *C = - ConstantInt::get(Type::ULongTy, (1ULL << SrcBitSize)-1); - C = ConstantExpr::getCast(C, CI.getType()); - return BinaryOperator::createAnd(Res, C); } - case Signext: - // We need to emit a cast to truncate, then a cast to sext. - return new CastInst(InsertCastBefore(Res, Src->getType(), CI), - CI.getType()); + + unsigned ShiftAmt = Log2_64(KnownZero^TypeMask); + Value *In = Op0; + if (ShiftAmt) { + // Perform a logical shr by shiftamt. + // Insert the shift to put the result in the low bit. + In = InsertNewInstBefore( + new ShiftInst(Instruction::LShr, In, + ConstantInt::get(Type::UByteTy, ShiftAmt), + In->getName()+".lobit"), CI); + } + + if ((Op1CV != 0) == isSetNE) { // Toggle the low bit. + Constant *One = ConstantInt::get(In->getType(), 1); + In = BinaryOperator::createXor(In, One, "tmp"); + InsertNewInstBefore(cast<Instruction>(In), CI); } + + if (CI.getType() == In->getType()) + return ReplaceInstUsesWith(CI, In); + else + return CastInst::createInferredCast(In, CI.getType()); } } - - const Type *DestTy = CI.getType(); - unsigned SrcBitSize = Src->getType()->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + } + break; + } + return 0; +} - Value *Op0 = SrcI->getNumOperands() > 0 ? SrcI->getOperand(0) : 0; - Value *Op1 = SrcI->getNumOperands() > 1 ? SrcI->getOperand(1) : 0; +Instruction *InstCombiner::visitTrunc(CastInst &CI) { + return commonIntCastTransforms(CI); +} - switch (SrcI->getOpcode()) { - case Instruction::Add: - case Instruction::Mul: - case Instruction::And: - case Instruction::Or: - case Instruction::Xor: - // If we are discarding information, or just changing the sign, rewrite. - if (DestBitSize <= SrcBitSize && DestBitSize != 1) { - // Don't insert two casts if they cannot be eliminated. We allow two - // casts to be inserted if the sizes are the same. This could only be - // converting signedness, which is a noop. - if (DestBitSize == SrcBitSize || !ValueRequiresCast(Op1, DestTy,TD) || - !ValueRequiresCast(Op0, DestTy, TD)) { - Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); - Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI); - return BinaryOperator::create(cast<BinaryOperator>(SrcI) - ->getOpcode(), Op0c, Op1c); - } - } +Instruction *InstCombiner::visitZExt(CastInst &CI) { + // If one of the common conversion will work .. + if (Instruction *Result = commonIntCastTransforms(CI)) + return Result; - // cast (xor bool X, true) to int --> xor (cast bool X to int), 1 - if (SrcBitSize == 1 && SrcI->getOpcode() == Instruction::Xor && - Op1 == ConstantBool::getTrue() && - (!Op0->hasOneUse() || !isa<SetCondInst>(Op0))) { - Value *New = InsertOperandCastBefore(Op0, DestTy, &CI); - return BinaryOperator::createXor(New, - ConstantInt::get(CI.getType(), 1)); - } - break; - case Instruction::SDiv: - case Instruction::UDiv: - case Instruction::SRem: - case Instruction::URem: - // If we are just changing the sign, rewrite. - if (DestBitSize == SrcBitSize) { - // Don't insert two casts if they cannot be eliminated. We allow two - // casts to be inserted if the sizes are the same. This could only be - // converting signedness, which is a noop. - if (!ValueRequiresCast(Op1, DestTy,TD) || - !ValueRequiresCast(Op0, DestTy, TD)) { - Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); - Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI); - return BinaryOperator::create( - cast<BinaryOperator>(SrcI)->getOpcode(), Op0c, Op1c); - } - } - break; + Value *Src = CI.getOperand(0); - case Instruction::Shl: - // Allow changing the sign of the source operand. Do not allow changing - // the size of the shift, UNLESS the shift amount is a constant. We - // must not change variable sized shifts to a smaller size, because it - // is undefined to shift more bits out than exist in the value. - if (DestBitSize == SrcBitSize || - (DestBitSize < SrcBitSize && isa<Constant>(Op1))) { - Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); - return new ShiftInst(Instruction::Shl, Op0c, Op1); - } - break; - case Instruction::AShr: - // If this is a signed shr, and if all bits shifted in are about to be - // truncated off, turn it into an unsigned shr to allow greater - // simplifications. - if (DestBitSize < SrcBitSize && - isa<ConstantInt>(Op1)) { - unsigned ShiftAmt = cast<ConstantInt>(Op1)->getZExtValue(); - if (SrcBitSize > ShiftAmt && SrcBitSize-ShiftAmt >= DestBitSize) { - // Insert the new logical shift right. - return new ShiftInst(Instruction::LShr, Op0, Op1); - } + // If this is a cast of a cast + if (CastInst *CSrc = dyn_cast<CastInst>(Src)) { // A->B->C cast + // If the operand of the ZEXT is a TRUNC then we are dealing with integral + // types and we can convert this to a logical AND if the sizes are just + // right. This will be much cheaper than the pair of casts. + // If this is a TRUNC followed by a ZEXT then we are dealing with integral + // types and if the sizes are just right we can convert this into a logical + // 'and' which will be much cheaper than the pair of casts. + if (isa<TruncInst>(CSrc)) { + // Get the sizes of the types involved + Value *A = CSrc->getOperand(0); + unsigned SrcSize = A->getType()->getPrimitiveSizeInBits(); + unsigned MidSize = CSrc->getType()->getPrimitiveSizeInBits(); + unsigned DstSize = CI.getType()->getPrimitiveSizeInBits(); + // If we're actually extending zero bits and the trunc is a no-op + if (MidSize < DstSize && SrcSize == DstSize) { + // Replace both of the casts with an And of the type mask. + uint64_t AndValue = CSrc->getType()->getIntegralTypeMask(); + Constant *AndConst = ConstantInt::get(A->getType(), AndValue); + Instruction *And = + BinaryOperator::createAnd(CSrc->getOperand(0), AndConst); + // Unfortunately, if the type changed, we need to cast it back. + if (And->getType() != CI.getType()) { + And->setName(CSrc->getName()+".mask"); + InsertNewInstBefore(And, CI); + And = CastInst::createInferredCast(And, CI.getType()); } - break; + return And; + } + } + } - case Instruction::SetEQ: - case Instruction::SetNE: - // We if we are just checking for a seteq of a single bit and casting it - // to an integer. If so, shift the bit to the appropriate place then - // cast to integer to avoid the comparison. - if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { - uint64_t Op1CV = Op1C->getZExtValue(); - // cast (X == 0) to int --> X^1 iff X has only the low bit set. - // cast (X == 0) to int --> (X>>1)^1 iff X has only the 2nd bit set. - // cast (X == 1) to int --> X iff X has only the low bit set. - // cast (X == 2) to int --> X>>1 iff X has only the 2nd bit set. - // cast (X != 0) to int --> X iff X has only the low bit set. - // cast (X != 0) to int --> X>>1 iff X has only the 2nd bit set. - // cast (X != 1) to int --> X^1 iff X has only the low bit set. - // cast (X != 2) to int --> (X>>1)^1 iff X has only the 2nd bit set. - if (Op1CV == 0 || isPowerOf2_64(Op1CV)) { - // If Op1C some other power of two, convert: - uint64_t KnownZero, KnownOne; - uint64_t TypeMask = Op1->getType()->getIntegralTypeMask(); - ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); - - if (isPowerOf2_64(KnownZero^TypeMask)) { // Exactly one possible 1? - bool isSetNE = SrcI->getOpcode() == Instruction::SetNE; - if (Op1CV && (Op1CV != (KnownZero^TypeMask))) { - // (X&4) == 2 --> false - // (X&4) != 2 --> true - Constant *Res = ConstantBool::get(isSetNE); - Res = ConstantExpr::getCast(Res, CI.getType()); - return ReplaceInstUsesWith(CI, Res); - } - - unsigned ShiftAmt = Log2_64(KnownZero^TypeMask); - Value *In = Op0; - if (ShiftAmt) { - // Perform a logical shr by shiftamt. - // Insert the shift to put the result in the low bit. - In = InsertNewInstBefore(new ShiftInst(Instruction::LShr, In, - ConstantInt::get(Type::UByteTy, ShiftAmt), - In->getName()+".lobit"), CI); - } - - if ((Op1CV != 0) == isSetNE) { // Toggle the low bit. - Constant *One = ConstantInt::get(In->getType(), 1); - In = BinaryOperator::createXor(In, One, "tmp"); - InsertNewInstBefore(cast<Instruction>(In), CI); - } - - if (CI.getType() == In->getType()) - return ReplaceInstUsesWith(CI, In); - else - return new CastInst(In, CI.getType()); - } - } - } - break; + return 0; +} + +Instruction *InstCombiner::visitSExt(CastInst &CI) { + return commonIntCastTransforms(CI); +} + +Instruction *InstCombiner::visitFPTrunc(CastInst &CI) { + return commonCastTransforms(CI); +} + +Instruction *InstCombiner::visitFPExt(CastInst &CI) { + return commonCastTransforms(CI); +} + +Instruction *InstCombiner::visitFPToUI(CastInst &CI) { + if (Instruction *I = commonCastTransforms(CI)) + return I; + + // FIXME. We currently implement cast-to-bool as a setne %X, 0. This is + // because codegen cannot accurately perform a truncate to bool operation. + // Something goes wrong in promotion to a larger type. When CodeGen can + // handle a proper truncation to bool, this should be removed. + Value *Src = CI.getOperand(0); + const Type *SrcTy = Src->getType(); + const Type *DestTy = CI.getType(); + if (DestTy == Type::BoolTy) + return BinaryOperator::createSetNE(Src, Constant::getNullValue(SrcTy)); + return 0; +} + +Instruction *InstCombiner::visitFPToSI(CastInst &CI) { + if (Instruction *I = commonCastTransforms(CI)) + return I; + + // FIXME. We currently implement cast-to-bool as a setne %X, 0. This is + // because codegen cannot accurately perform a truncate to bool operation. + // Something goes wrong in promotion to a larger type. When CodeGen can + // handle a proper truncation to bool, this should be removed. + Value *Src = CI.getOperand(0); + const Type *SrcTy = Src->getType(); + const Type *DestTy = CI.getType(); + if (DestTy == Type::BoolTy) + return BinaryOperator::createSetNE(Src, Constant::getNullValue(SrcTy)); + return 0; +} + +Instruction *InstCombiner::visitUIToFP(CastInst &CI) { + return commonCastTransforms(CI); +} + +Instruction *InstCombiner::visitSIToFP(CastInst &CI) { + return commonCastTransforms(CI); +} + +Instruction *InstCombiner::visitPtrToInt(CastInst &CI) { + if (Instruction *I = commonCastTransforms(CI)) + return I; + + // FIXME. We currently implement cast-to-bool as a setne %X, 0. This is + // because codegen cannot accurately perform a truncate to bool operation. + // Something goes wrong in promotion to a larger type. When CodeGen can + // handle a proper truncation to bool, this should be removed. + Value *Src = CI.getOperand(0); + const Type *SrcTy = Src->getType(); + const Type *DestTy = CI.getType(); + if (DestTy == Type::BoolTy) + return BinaryOperator::createSetNE(Src, Constant::getNullValue(SrcTy)); + return 0; +} + +Instruction *InstCombiner::visitIntToPtr(CastInst &CI) { + return commonCastTransforms(CI); +} + +Instruction *InstCombiner::visitBitCast(CastInst &CI) { + + // If the operands are integer typed then apply the integer transforms, + // otherwise just apply the common ones. + Value *Src = CI.getOperand(0); + const Type *SrcTy = Src->getType(); + const Type *DestTy = CI.getType(); + + if (SrcTy->isInteger() && DestTy->isInteger()) { + if (Instruction *Result = commonIntCastTransforms(CI)) + return Result; + } else { + if (Instruction *Result = commonCastTransforms(CI)) + return Result; + } + + + // Get rid of casts from one type to the same type. These are useless and can + // be replaced by the operand. + if (DestTy == Src->getType()) + return ReplaceInstUsesWith(CI, Src); + + // If the source and destination are pointers, and this cast is equivalent to + // a getelementptr X, 0, 0, 0... turn it into the appropriate getelementptr. + // This can enhance SROA and other transforms that want type-safe pointers. + if (const PointerType *DstPTy = dyn_cast<PointerType>(DestTy)) { + if (const PointerType *SrcPTy = dyn_cast<PointerType>(SrcTy)) { + const Type *DstElTy = DstPTy->getElementType(); + const Type *SrcElTy = SrcPTy->getElementType(); + + Constant *ZeroUInt = Constant::getNullValue(Type::UIntTy); + unsigned NumZeros = 0; + while (SrcElTy != DstElTy && + isa<CompositeType>(SrcElTy) && !isa<PointerType>(SrcElTy) && + SrcElTy->getNumContainedTypes() /* not "{}" */) { + SrcElTy = cast<CompositeType>(SrcElTy)->getTypeAtIndex(ZeroUInt); + ++NumZeros; + } + + // If we found a path from the src to dest, create the getelementptr now. + if (SrcElTy == DstElTy) { + std::vector<Value*> Idxs(NumZeros+1, ZeroUInt); + return new GetElementPtrInst(Src, Idxs); } } - - if (SrcI->hasOneUse()) { - if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(SrcI)) { - // Okay, we have (cast (shuffle ..)). We know this cast is a bitconvert - // because the inputs are known to be a vector. Check to see if this is - // a cast to a vector with the same # elts. - if (isa<PackedType>(CI.getType()) && - cast<PackedType>(CI.getType())->getNumElements() == - SVI->getType()->getNumElements()) { - CastInst *Tmp; - // If either of the operands is a cast from CI.getType(), then - // evaluating the shuffle in the casted destination's type will allow - // us to eliminate at least one cast. - if (((Tmp = dyn_cast<CastInst>(SVI->getOperand(0))) && - Tmp->getOperand(0)->getType() == CI.getType()) || - ((Tmp = dyn_cast<CastInst>(SVI->getOperand(1))) && - Tmp->getOperand(0)->getType() == CI.getType())) { - Value *LHS = InsertOperandCastBefore(SVI->getOperand(0), - CI.getType(), &CI); - Value *RHS = InsertOperandCastBefore(SVI->getOperand(1), - CI.getType(), &CI); - // Return a new shuffle vector. Use the same element ID's, as we - // know the vector types match #elts. - return new ShuffleVectorInst(LHS, RHS, SVI->getOperand(2)); - } + } + + if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(Src)) { + if (SVI->hasOneUse()) { + // Okay, we have (bitconvert (shuffle ..)). Check to see if this is + // a bitconvert to a vector with the same # elts. + if (isa<PackedType>(DestTy) && + cast<PackedType>(DestTy)->getNumElements() == + SVI->getType()->getNumElements()) { + CastInst *Tmp; + // If either of the operands is a cast from CI.getType(), then + // evaluating the shuffle in the casted destination's type will allow + // us to eliminate at least one cast. + if (((Tmp = dyn_cast<CastInst>(SVI->getOperand(0))) && + Tmp->getOperand(0)->getType() == DestTy) || + ((Tmp = dyn_cast<CastInst>(SVI->getOperand(1))) && + Tmp->getOperand(0)->getType() == DestTy)) { + Value *LHS = InsertOperandCastBefore(SVI->getOperand(0), DestTy, &CI); + Value *RHS = InsertOperandCastBefore(SVI->getOperand(1), DestTy, &CI); + // Return a new shuffle vector. Use the same element ID's, as we + // know the vector types match #elts. + return new ShuffleVectorInst(LHS, RHS, SVI->getOperand(2)); } } } } - return 0; } @@ -6108,7 +6213,7 @@ Instruction *InstCombiner::FoldSelectOpOp(SelectInst &SI, Instruction *TI, if (TI->getNumOperands() == 1) { // If this is a non-volatile load or a cast from the same type, // merge. - if (TI->getOpcode() == Instruction::Cast) { + if (TI->isCast()) { if (TI->getOperand(0)->getType() != FI->getOperand(0)->getType()) return 0; } else { @@ -6119,7 +6224,8 @@ Instruction *InstCombiner::FoldSelectOpOp(SelectInst &SI, Instruction *TI, SelectInst *NewSI = new SelectInst(SI.getCondition(), TI->getOperand(0), FI->getOperand(0), SI.getName()+".v"); InsertNewInstBefore(NewSI, SI); - return new CastInst(NewSI, TI->getType()); + return CastInst::create(Instruction::CastOps(TI->getOpcode()), NewSI, + TI->getType()); } // Only handle binary operators here. @@ -6228,13 +6334,13 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) { // select C, 1, 0 -> cast C to int if (FalseValC->isNullValue() && TrueValC->getZExtValue() == 1) { - return new CastInst(CondVal, SI.getType()); + return CastInst::create(Instruction::ZExt, CondVal, SI.getType()); } else if (TrueValC->isNullValue() && FalseValC->getZExtValue() == 1) { // select C, 0, 1 -> cast !C to int Value *NotCond = InsertNewInstBefore(BinaryOperator::createNot(CondVal, "not."+CondVal->getName()), SI); - return new CastInst(NotCond, SI.getType()); + return CastInst::create(Instruction::ZExt, NotCond, SI.getType()); } if (SetCondInst *IC = dyn_cast<SetCondInst>(SI.getCondition())) { @@ -6255,24 +6361,24 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { if (CanXForm) { // The comparison constant and the result are not neccessarily the - // same width. In any case, the first step to do is make sure - // that X is signed. + // same width. Make an all-ones value by inserting a AShr. Value *X = IC->getOperand(0); - if (!X->getType()->isSigned()) - X = InsertCastBefore(X, X->getType()->getSignedVersion(), SI); - - // Now that X is signed, we have to make the all ones value. Do - // this by inserting a new SRA. unsigned Bits = X->getType()->getPrimitiveSizeInBits(); Constant *ShAmt = ConstantInt::get(Type::UByteTy, Bits-1); Instruction *SRA = new ShiftInst(Instruction::AShr, X, ShAmt, "ones"); InsertNewInstBefore(SRA, SI); - // Finally, convert to the type of the select RHS. If this is - // smaller than the compare value, it will truncate the ones to - // fit. If it is larger, it will sext the ones to fit. - return new CastInst(SRA, SI.getType()); + // Finally, convert to the type of the select RHS. We figure out + // if this requires a SExt, Trunc or BitCast based on the sizes. + Instruction::CastOps opc = Instruction::BitCast; + unsigned SRASize = SRA->getType()->getPrimitiveSizeInBits(); + unsigned SISize = SI.getType()->getPrimitiveSizeInBits(); + if (SRASize < SISize) + opc = Instruction::SExt; + else if (SRASize > SISize) + opc = Instruction::Trunc; + return CastInst::create(opc, SRA, SI.getType()); } } @@ -6470,9 +6576,9 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) { } } return Align; - } else if (isa<CastInst>(V) || + } else if (isa<BitCastInst>(V) || (isa<ConstantExpr>(V) && - cast<ConstantExpr>(V)->getOpcode() == Instruction::Cast)) { + cast<ConstantExpr>(V)->getOpcode() == Instruction::BitCast)) { User *CI = cast<User>(V); if (isa<PointerType>(CI->getOperand(0)->getType())) return GetKnownAlignment(CI->getOperand(0), TD); @@ -6667,7 +6773,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { Result = new InsertElementInst(Result, ExtractedElts[Idx], i,"tmp"); InsertNewInstBefore(cast<Instruction>(Result), CI); } - return new CastInst(Result, CI.getType()); + return CastInst::create(Instruction::BitCast, Result, CI.getType()); } } break; @@ -6769,7 +6875,7 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) { // If this cast does not effect the value passed through the varargs // area, we can eliminate the use of the cast. Value *Op = CI->getOperand(0); - if (CI->getType()->isLosslesslyConvertibleTo(Op->getType())) { + if (CI->isLosslessCast()) { *I = Op; Changed = true; } @@ -6785,7 +6891,8 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) { bool InstCombiner::transformConstExprCastCall(CallSite CS) { if (!isa<ConstantExpr>(CS.getCalledValue())) return false; ConstantExpr *CE = cast<ConstantExpr>(CS.getCalledValue()); - if (CE->getOpcode() != Instruction::Cast || !isa<Function>(CE->getOperand(0))) + if (CE->getOpcode() != Instruction::BitCast || + !isa<Function>(CE->getOperand(0))) return false; Function *Callee = cast<Function>(CE->getOperand(0)); Instruction *Caller = CS.getInstruction(); @@ -6800,10 +6907,11 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { // Check to see if we are changing the return type... if (OldRetTy != FT->getReturnType()) { if (Callee->isExternal() && - !(OldRetTy->isLosslesslyConvertibleTo(FT->getReturnType()) || + !Caller->use_empty() && + !(OldRetTy->canLosslesslyBitCastTo(FT->getReturnType()) || (isa<PointerType>(FT->getReturnType()) && - TD->getIntPtrType()->isLosslesslyConvertibleTo(OldRetTy))) - && !Caller->use_empty()) + TD->getIntPtrType()->canLosslesslyBitCastTo(OldRetTy))) + ) return false; // Cannot transform this return value... // If the callsite is an invoke instruction, and the return value is used by @@ -6827,9 +6935,9 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { for (unsigned i = 0, e = NumCommonArgs; i != e; ++i, ++AI) { const Type *ParamTy = FT->getParamType(i); const Type *ActTy = (*AI)->getType(); - ConstantInt* c = dyn_cast<ConstantInt>(*AI); + ConstantInt *c = dyn_cast<ConstantInt>(*AI); //Either we can cast directly, or we can upconvert the argument - bool isConvertible = ActTy->isLosslesslyConvertibleTo(ParamTy) || + bool isConvertible = ActTy->canLosslesslyBitCastTo(ParamTy) || (ParamTy->isIntegral() && ActTy->isIntegral() && ParamTy->isSigned() == ActTy->isSigned() && ParamTy->getPrimitiveSize() >= ActTy->getPrimitiveSize()) || @@ -6853,8 +6961,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { if ((*AI)->getType() == ParamTy) { Args.push_back(*AI); } else { - Args.push_back(InsertNewInstBefore(new CastInst(*AI, ParamTy, "tmp"), - *Caller)); + CastInst *NewCast = CastInst::createInferredCast(*AI, ParamTy, "tmp"); + Args.push_back(InsertNewInstBefore(NewCast, *Caller)); } } @@ -6874,7 +6982,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { const Type *PTy = getPromotedType((*AI)->getType()); if (PTy != (*AI)->getType()) { // Must promote to pass through va_arg area! - Instruction *Cast = new CastInst(*AI, PTy, "tmp"); + Instruction *Cast = CastInst::createInferredCast(*AI, PTy, "tmp"); InsertNewInstBefore(Cast, *Caller); Args.push_back(Cast); } else { @@ -6902,7 +7010,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { Value *NV = NC; if (Caller->getType() != NV->getType() && !Caller->use_empty()) { if (NV->getType() != Type::VoidTy) { - NV = NC = new CastInst(NC, Caller->getType(), "tmp"); + NV = NC = CastInst::createInferredCast(NC, Caller->getType(), "tmp"); // If this is an invoke instruction, we should insert it after the first // non-phi, instruction in the normal successor block. @@ -7107,8 +7215,8 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { } // Insert and return the new operation. - if (isa<CastInst>(FirstInst)) - return new CastInst(PhiVal, PN.getType()); + if (CastInst* FirstCI = dyn_cast<CastInst>(FirstInst)) + return CastInst::create(FirstCI->getOpcode(), PhiVal, PN.getType()); else if (isa<LoadInst>(FirstInst)) return new LoadInst(PhiVal, "", isVolatile); else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) @@ -7358,7 +7466,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { // Replace all uses of the GEP with the new constexpr... return ReplaceInstUsesWith(GEP, CE); } - } else if (Value *X = isCast(PtrOp)) { // Is the operand a cast? + } else if (Value *X = getBitCastOperand(PtrOp)) { // Is the operand a cast? if (!isa<PointerType>(X->getType())) { // Not interesting. Source pointer must be a cast from pointer. } else if (HasZeroPointerIndex) { @@ -7393,7 +7501,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { Value *V = InsertNewInstBefore( new GetElementPtrInst(X, Constant::getNullValue(Type::IntTy), GEP.getOperand(1), GEP.getName()), GEP); - return new CastInst(V, GEP.getType()); + // V and GEP are both pointer types --> BitCast + return new BitCastInst(V, GEP.getType()); } // Transform things like: @@ -7446,11 +7555,12 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { } // Insert the new GEP instruction. - Instruction *Idx = + Instruction *NewGEP = new GetElementPtrInst(X, Constant::getNullValue(Type::IntTy), NewIdx, GEP.getName()); - Idx = InsertNewInstBefore(Idx, GEP); - return new CastInst(Idx, GEP.getType()); + NewGEP = InsertNewInstBefore(NewGEP, GEP); + // The NewGEP must be pointer typed, so must the old one -> BitCast + return new BitCastInst(NewGEP, GEP.getType()); } } } @@ -7572,7 +7682,7 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI) { CI->getName(), LI.isVolatile()),LI); // Now cast the result of the load. - return new CastInst(NewLoad, LI.getType()); + return CastInst::createInferredCast(NewLoad, LI.getType()); } } } @@ -7675,7 +7785,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType())); } - } else if (CE->getOpcode() == Instruction::Cast) { + } else if (CE->isCast()) { if (Instruction *Res = InstCombineLoadCast(*this, LI)) return Res; } @@ -7755,9 +7865,9 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { if (Constant *C = dyn_cast<Constant>(SI.getOperand(0))) NewCast = ConstantExpr::getCast(C, SrcPTy); else - NewCast = IC.InsertNewInstBefore(new CastInst(SI.getOperand(0), - SrcPTy, - SI.getOperand(0)->getName()+".c"), SI); + NewCast = IC.InsertNewInstBefore( + CastInst::createInferredCast(SI.getOperand(0), SrcPTy, + SI.getOperand(0)->getName()+".c"), SI); return new StoreInst(NewCast, CastOp); } @@ -7841,7 +7951,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { if (Instruction *Res = InstCombineStoreToCast(*this, SI)) return Res; if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) if (Instruction *Res = InstCombineStoreToCast(*this, SI)) return Res; diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index 2a790f21a7..5816e5c700 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -384,6 +384,7 @@ bool LICM::canSinkOrHoistInst(Instruction &I) { return false; } + // Otherwise these instructions are hoistable/sinkable return isa<BinaryOperator>(I) || isa<ShiftInst>(I) || isa<CastInst>(I) || isa<SelectInst>(I) || isa<GetElementPtrInst>(I); } diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 3ac4df7c99..f6551ee076 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -627,10 +627,9 @@ static bool isTargetConstant(const SCEVHandle &V, const TargetLowering *TLI) { if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V)) if (ConstantExpr *CE = dyn_cast<ConstantExpr>(SU->getValue())) - if (CE->getOpcode() == Instruction::Cast) { + if (CE->getOpcode() == Instruction::PtrToInt) { Constant *Op0 = CE->getOperand(0); - if (isa<GlobalValue>(Op0) && - TLI && + if (isa<GlobalValue>(Op0) && TLI && TLI->isLegalAddressImmediate(cast<GlobalValue>(Op0))) return true; } @@ -899,7 +898,7 @@ unsigned LoopStrengthReduce::CheckForIVReuse(const SCEVHandle &Stride, // FIXME: Only handle base == 0 for now. // Only reuse previous IV if it would not require a type conversion. if (isZero(II->Base) && - II->Base->getType()->isLosslesslyConvertibleTo(Ty)) { + II->Base->getType()->canLosslesslyBitCastTo(Ty)) { IV = *II; return Scale; } @@ -1044,9 +1043,10 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, if (!C || (!C->isNullValue() && !isTargetConstant(SCEVUnknown::get(CommonBaseV), TLI))) - // We want the common base emitted into the preheader! - CommonBaseV = new CastInst(CommonBaseV, CommonBaseV->getType(), - "commonbase", PreInsertPt); + // We want the common base emitted into the preheader! This is just + // using cast as a copy so BitCast (no-op cast) is appropriate + CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV->getType(), + "commonbase", PreInsertPt); } // We want to emit code for users inside the loop first. To do this, we @@ -1092,12 +1092,13 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, // If BaseV is a constant other than 0, make sure that it gets inserted into // the preheader, instead of being forward substituted into the uses. We do - // this by forcing a noop cast to be inserted into the preheader in this - // case. + // this by forcing a BitCast (noop cast) to be inserted into the preheader + // in this case. if (Constant *C = dyn_cast<Constant>(BaseV)) { if (!C->isNullValue() && !isTargetConstant(Base, TLI)) { - // We want this constant emitted into the preheader! - BaseV = new CastInst(BaseV, BaseV->getType(), "preheaderinsert", + // We want this constant emitted into the preheader! This is just + // using cast as a copy so BitCast (no-op cast) is appropriate + BaseV = new BitCastInst(BaseV, BaseV->getType(), "preheaderinsert", PreInsertPt); } } diff --git a/lib/Transforms/Scalar/LowerGC.cpp b/lib/Transforms/Scalar/LowerGC.cpp index 6a07691adb..fdfbf7f11c 100644 --- a/lib/Transforms/Scalar/LowerGC.cpp +++ b/lib/Transforms/Scalar/LowerGC.cpp @@ -139,13 +139,15 @@ bool LowerGC::doInitialization(Module &M) { } /// Coerce - If the specified operand number of the specified instruction does -/// not have the specified type, insert a cast. +/// not have the specified type, insert a cast. Note that this only uses BitCast +/// because the types involved are all pointers. static void Coerce(Instruction *I, unsigned OpNum, Type *Ty) { if (I->getOperand(OpNum)->getType() != Ty) { if (Constant *C = dyn_cast<Constant>(I->getOperand(OpNum))) - I->setOperand(OpNum, ConstantExpr::getCast(C, Ty)); + I->setOperand(OpNum, ConstantExpr::getBitCast(C, Ty)); else { - CastInst *CI = new CastInst(I->getOperand(OpNum), Ty, "", I); + CastInst *CI = + CastInst::createInferredCast(I->getOperand(OpNum), Ty, "", I); I->setOperand(OpNum, CI); } } @@ -196,7 +198,9 @@ bool LowerGC::runOnFunction(Function &F) { CallInst *NC = new CallInst(GCRead, CI->getOperand(1), CI->getOperand(2), CI->getName(), CI); - Value *NV = new CastInst(NC, CI->getType(), "", CI); + // These functions only deal with ptr type results so BitCast + // is the correct kind of cast (no-op cast). + Value *NV = new BitCastInst(NC, CI->getType(), "", CI); CI->replaceAllUsesWith(NV); BB->getInstList().erase(CI); CI = NC; @@ -273,7 +277,7 @@ bool LowerGC::runOnFunction(Function &F) { // Now that the record is all initialized, store the pointer into the global // pointer. - Value *C = new CastInst(AI, PointerType::get(MainRootRecordType), "", IP); + Value *C = new BitCastInst(AI, PointerType::get(MainRootRecordType), "", IP); new StoreInst(C, RootChain, IP); // On exit from the function we have to remove the entry from the GC root diff --git a/lib/Transforms/Scalar/LowerPacked.cpp b/lib/Transforms/Scalar/LowerPacked.cpp index ae8506e2fc..f02c40f4d8 100644 --- a/lib/Transforms/Scalar/LowerPacked.cpp +++ b/lib/Transforms/Scalar/LowerPacked.cpp @@ -212,11 +212,9 @@ void LowerPacked::visitLoadInst(LoadInst& LI) PKT->getNumElements()); PointerType* APT = PointerType::get(AT); - // Cast the packed type to an array - Value* array = new CastInst(LI.getPointerOperand(), - APT, - LI.getName() + ".a", - &LI); + // Cast the pointer to packed type to an equivalent array + Value* array = new BitCastInst(LI.getPointerOperand(), APT, + LI.getName() + ".a", &LI); // Convert this load into num elements number of loads std::vector<Value*> values; @@ -234,10 +232,8 @@ void LowerPacked::visitLoadInst(LoadInst& LI) &LI); // generate the new load and save the result in packedToScalar map - values.push_back(new LoadInst(val, - LI.getName()+"."+utostr(i), - LI.isVolatile(), - &LI)); + values.push_back(new LoadInst(val, LI.getName()+"."+utostr(i), + LI.isVolatile(), &LI)); } setValues(&LI,values); @@ -286,11 +282,10 @@ void LowerPacked::visitStoreInst(StoreInst& SI) PKT->getNumElements()); PointerType* APT = PointerType::get(AT); - // cast the packed to an array type - Value* array = new CastInst(SI.getPointerOperand(), - APT, - "store.ge.a.", - &SI); + // Cast the pointer to packed to an array of equivalent type + Value* array = new BitCastInst(SI.getPointerOperand(), APT, + "store.ge.a.", &SI); + std::vector<Value*>& values = getValues(SI.getOperand(0)); assert((values.size() == PKT->getNumElements()) && diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index a0c516402b..b62df63215 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -624,7 +624,8 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { assert((NV->getType()->isInteger() || isa<PointerType>(NV->getType())) && "Unknown promotion!"); } - NV = new CastInst(NV, LI->getType(), LI->getName(), LI); + NV = CastInst::createInferredCast(NV, LI->getType(), LI->getName(), + LI); } } LI->replaceAllUsesWith(NV); @@ -646,12 +647,12 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { ConstantInt::get(Type::UIntTy, Elt), "tmp", SI); } else { - // If SV is signed, convert it to unsigned, so that the next cast zero - // extends the value. + // Always zero extend the value. if (SV->getType()->isSigned()) - SV = new CastInst(SV, SV->getType()->getUnsignedVersion(), - SV->getName(), SI); - SV = new CastInst(SV, Old->getType(), SV->getName(), SI); + SV = CastInst::createInferredCast(SV, + SV->getType()->getUnsignedVersion(), SV->getName(), SI); + SV = CastInst::createInferredCast(SV, Old->getType(), SV->getName(), + SI); if (Offset && Offset < TD.getTypeSize(SV->getType())*8) SV = new ShiftInst(Instruction::Shl, SV, ConstantInt::get(Type::UByteTy, Offset), diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 9a16bfccb3..366a95c49c 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -122,8 +122,19 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy, case Instruction::LShr: case Instruction::AShr: return ConstantExpr::get(Opc, Ops[0], Ops[1]); - case Instruction::Cast: - return ConstantExpr::getCast(Ops[0], DestTy); + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + return ConstantExpr::getCast(Opc, Ops[0], DestTy); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); case Instruction::ExtractElement: diff --git a/lib/Transforms/Utils/LowerAllocations.cpp b/lib/Transforms/Utils/LowerAllocations.cpp index d08235cd9d..b7e4040145 100644 --- a/lib/Transforms/Utils/LowerAllocations.cpp +++ b/lib/Transforms/Utils/LowerAllocations.cpp @@ -134,7 +134,7 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { } else { Value *Scale = MI->getOperand(0); if (Scale->getType() != IntPtrTy) - Scale = new CastInst(Scale, IntPtrTy, "", I); + Scale = CastInst::createInferredCast(Scale, IntPtrTy, "", I); // Multiply it by the array size if necessary... MallocArg = BinaryOperator::create(Instruction::Mul, Scale, @@ -148,10 +148,13 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { if (MallocFTy->getNumParams() > 0 || MallocFTy->isVarArg()) { if (MallocFTy->isVarArg()) { if (MallocArg->getType() != IntPtrTy) - MallocArg = new CastInst(MallocArg, IntPtrTy, "", I); + MallocArg = CastInst::createInferredCast(MallocArg, IntPtrTy, "", + I); } else if (MallocFTy->getNumParams() > 0 && MallocFTy->getParamType(0) != Type::UIntTy) - MallocArg = new CastInst(MallocArg, MallocFTy->getParamType(0), "",I); + MallocArg = + CastInst::createInferredCast(MallocArg, MallocFTy->getParamType(0), + "",I); MallocArgs.push_back(MallocArg); } @@ -166,7 +169,7 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { // Create a cast instruction to convert to the right type... Value *MCast; if (MCall->getType() != Type::VoidTy) - MCast = new CastInst(MCall, MI->getType(), "", I); + MCast = CastInst::createInferredCast(MCall, MI->getType(), "", I); else MCast = Constant::getNullValue(MI->getType()); @@ -183,7 +186,8 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { Value *MCast = FI->getOperand(0); if (FreeFTy->getNumParams() > 0 && FreeFTy->getParamType(0) != MCast->getType()) - MCast = new CastInst(MCast, FreeFTy->getParamType(0), "", I); + MCast = CastInst::createInferredCast(MCast, FreeFTy->getParamType(0), + "", I); FreeArgs.push_back(MCast); } diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp index 3385ba1c64..507fb86f56 100644 --- a/lib/Transforms/Utils/LowerInvoke.cpp +++ b/lib/Transforms/Utils/LowerInvoke.cpp @@ -326,7 +326,7 @@ splitLiveRangesLiveAcrossInvokes(std::vector<InvokeInst*> &Invokes) { Function *F = Invokes.back()->getParent()->getParent(); // To avoid having to handle incoming arguments specially, we lower each arg - // to a copy instruction in the entry block. This ensure that the argument + // to a copy instruction in the entry block. This ensures that the argument // value itself cannot be live across the entry block. BasicBlock::iterator AfterAllocaInsertPt = F->begin()->begin(); while (isa<AllocaInst>(AfterAllocaInsertPt) && @@ -334,10 +334,16 @@ splitLiveRangesLiveAcrossInvokes(std::vector<InvokeInst*> &Invokes) { ++AfterAllocaInsertPt; for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI) { - CastInst *NC = new CastInst(AI, AI->getType(), AI->getName()+".tmp", - AfterAllocaInsertPt); + // This is always a no-op cast because we're casting AI to AI->getType() so + // src and destination types are identical. BitCast is the only possibility. + CastInst *NC = new BitCastInst( + AI, AI->getType(), AI->getName()+".tmp", AfterAllocaInsertPt); AI->replaceAllUsesWith(NC); - NC->setOperand(0, AI); + // Normally its is forbidden to replace a CastInst's operand because it + // could cause the opcode to reflect an illegal conversion. However, we're + // replacing it here with the same value it was constructed with to simply + // make NC its user. + NC->setOperand(0, AI); } // Finally, scan the code looking for instructions with bad live ranges. diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index a17e7f1399..8d4cb83e17 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -425,11 +425,6 @@ static Value *GatherConstantSetNEs(Value *V, std::vector<ConstantInt*> &Values){ Values.push_back(C); return Inst->getOperand(1); } - } else if (Inst->getOpcode() == Instruction::Cast) { - // Cast of X to bool is really a comparison against zero. - assert(Inst->getType() == Type::BoolTy && "Can only handle bool values!"); - Values.push_back(ConstantInt::get(Inst->getOperand(0)->getType(), 0)); - return Inst->getOperand(0); } else if (Inst->getOpcode() == Instruction::And) { if (Value *LHS = GatherConstantSetNEs(Inst->getOperand(0), Values)) if (Value *RHS = GatherConstantSetNEs(Inst->getOperand(1), Values)) diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 4f2cbc42fc..8ff55b6640 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -541,10 +541,11 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, Out << ", "; } - if (CE->getOpcode() == Instruction::Cast) { + if (CE->isCast()) { Out << " to "; printTypeInt(Out, CE->getType(), TypeTable); } + Out << ')'; } else { diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index 1529d1bf1f..57a09e2d07 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -206,8 +206,8 @@ static Value *CastArg(Value *Arg, const Type *Ty, Instruction *InsertBefore) { if (Constant *C = dyn_cast<Constant>(Arg)) { return ConstantExpr::getCast(C, Ty); } else { - Value *Cast = new CastInst(Arg, Ty, "autoupgrade_cast", InsertBefore); - return Cast; + return CastInst::createInferredCast(Arg, Ty, "autoupgrade_cast", + InsertBefore); } } @@ -261,8 +261,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Instruction *RetVal = NewCI; if (F->getReturnType() != NewFn->getReturnType()) { - RetVal = new CastInst(NewCI, F->getReturnType(), - NewCI->getName(), CI); + RetVal = + new BitCastInst(NewCI, F->getReturnType(), NewCI->getName(), CI); NewCI->moveBefore(RetVal); } diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 64dd1b1234..9974071385 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -507,7 +507,7 @@ struct VISIBILITY_HIDDEN DirectIntRules // Casting operators. ick #define DEF_CAST(TYPE, CLASS, CTYPE) \ static Constant *CastTo##TYPE (const ConstantInt *V) { \ - return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getZExtValue()); \ + return CLASS::get(Type::TYPE##Ty, (CTYPE)((BuiltinType)V->getZExtValue()));\ } DEF_CAST(Bool , ConstantBool, bool) @@ -721,15 +721,6 @@ ConstRules &ConstRules::get(const Constant *V1, const Constant *V2) { //===----------------------------------------------------------------------===// // ConstantFold*Instruction Implementations //===----------------------------------------------------------------------===// -// -// These methods contain the special case hackery required to symbolically -// evaluate some constant expression cases, and use the ConstantRules class to -// evaluate normal constants. -// -static unsigned getSize(const Type *Ty) { - unsigned S = Ty->getPrimitiveSize(); - return S ? S : 8; // Treat pointers at 8 bytes -} /// CastConstantPacked - Convert the specified ConstantPacked node to the /// specified packed type. At this point, we know that the elements of the @@ -746,17 +737,20 @@ static Constant *CastConstantPacked(ConstantPacked *CP, if (SrcNumElts == DstNumElts) { std::vector<Constant*> Result; - // If the src and dest elements are both integers, just cast each one - // which will do the appropriate bit-convert. - if (SrcEltTy->isIntegral() && DstEltTy->isIntegral()) { + // If the src and dest elements are both integers, or both floats, we can + // just BitCast each element because the elements are the same size. + if ((SrcEltTy->isIntegral() && DstEltTy->isIntegral()) || + (SrcEltTy->isFloatingPoint() && DstEltTy->isFloatingPoint())) { for (unsigned i = 0; i != SrcNumElts; ++i) - Result.push_back(ConstantExpr::getCast(CP->getOperand(i), - DstEltTy)); + Result.push_back( + ConstantExpr::getCast(Instruction::BitCast, CP->getOperand(1), + DstEltTy)); return ConstantPacked::get(Result); } + // If this is an int-to-fp cast .. if (SrcEltTy->isIntegral()) { - // Otherwise, this is an int-to-fp cast. + // Ensure that it is int-to-fp cast assert(DstEltTy->isFloatingPoint()); if (DstEltTy->getTypeID() == Type::DoubleTyID) { for (unsigned i = 0; i != SrcNumElts; ++i) { @@ -805,34 +799,50 @@ static Constant *CastConstantPacked(ConstantPacked *CP, return 0; } +/// This function determines which opcode to use to fold two constant cast +/// expressions together. It uses CastInst::isEliminableCastPair to determine +/// the opcode. Consequently its just a wrapper around that function. +/// @Determine if it is valid to fold a cast of a cast +static unsigned +foldConstantCastPair( + unsigned opc, ///< opcode of the second cast constant expression + const ConstantExpr*Op, ///< the first cast constant expression + const Type *DstTy ///< desintation type of the first cast +) { + assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!"); + assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type"); + assert(CastInst::isCast(opc) && "Invalid cast opcode"); + + // The the types and opcodes for the two Cast constant expressions + const Type *SrcTy = Op->getOperand(0)->getType(); + const Type *MidTy = Op->getType(); + Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode()); + Instruction::CastOps secondOp = Instruction::CastOps(opc); + + // Let CastInst::isEliminableCastPair do the heavy lifting. + return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy, + Type::ULongTy); +} -Constant *llvm::ConstantFoldCastInstruction(const Constant *V, +Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, const Type *DestTy) { - if (V->getType() == DestTy) return (Constant*)V; - - // Cast of a global address to boolean is always true. - if (isa<GlobalValue>(V)) { - if (DestTy == Type::BoolTy) - // FIXME: When we support 'external weak' references, we have to prevent - // this transformation from happening. This code will need to be updated - // to ignore external weak symbols when we support it. - return ConstantBool::getTrue(); - } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::Cast) { - Constant *Op = const_cast<Constant*>(CE->getOperand(0)); - // Try to not produce a cast of a cast, which is almost always redundant. - if (!Op->getType()->isFloatingPoint() && - !CE->getType()->isFloatingPoint() && - !DestTy->isFloatingPoint()) { - unsigned S1 = getSize(Op->getType()), S2 = getSize(CE->getType()); - unsigned S3 = getSize(DestTy); - if (Op->getType() == DestTy && S3 >= S2) - return Op; - if (S1 >= S2 && S2 >= S3) - return ConstantExpr::getCast(Op, DestTy); - if (S1 <= S2 && S2 >= S3 && S1 <= S3) - return ConstantExpr::getCast(Op, DestTy); - } + const Type *SrcTy = V->getType(); + + // Handle some simple cases + if (SrcTy == DestTy) + return (Constant*)V; // no-op cast + + if (isa<UndefValue>(V)) + return UndefValue::get(DestTy); + + // If the cast operand is a constant expression, there's a few things we can + // do to try to simplify it. + if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { + if (CE->isCast()) { + // Try hard to fold cast of cast because they are almost always + // eliminable. + if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy)) + return ConstantExpr::getCast(newOpc, CE->getOperand(0), DestTy); } else if (CE->getOpcode() == Instruction::GetElementPtr) { // If all of the indexes in the GEP are null values, there is no pointer // adjustment going on. We might as well cast the source pointer. @@ -845,69 +855,132 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, if (isAllNull) return ConstantExpr::getCast(CE->getOperand(0), DestTy); } - } else if (isa<UndefValue>(V)) { - return UndefValue::get(DestTy); } - // Check to see if we are casting an pointer to an aggregate to a pointer to - // the first element. If so, return the appropriate GEP instruction. - if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) - if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy)) { - std::vector<Value*> IdxList; - IdxList.push_back(Constant::getNullValue(Type::IntTy)); - const Type *ElTy = PTy->getElementType(); - while (ElTy != DPTy->getElementType()) { - if (const StructType *STy = dyn_cast<StructType>(ElTy)) { - if (STy->getNumElements() == 0) break; - ElTy = STy->getElementType(0); - IdxList.push_back(Constant::getNullValue(Type::UIntTy)); - } else if (const SequentialType *STy = dyn_cast<SequentialType>(ElTy)) { - if (isa<PointerType>(ElTy)) break; // Can't index into pointers! - ElTy = STy->getElementType(); - IdxList.push_back(IdxList[0]); - } else { - break; - } - } + // We actually have to do a cast now, but first, we might need to fix up + // the value of the operand. + switch (opc) { + case Instruction::FPTrunc: + case Instruction::Trunc: + case Instruction::FPExt: + break; // floating point input & output, no fixup needed + case Instruction::FPToUI: { + ConstRules &Rules = ConstRules::get(V, V); + V = Rules.castToULong(V); // make sure we get an unsigned value first + break; + } + case Instruction::FPToSI: { + ConstRules &Rules = ConstRules::get(V, V); + V = Rules.castToLong(V); // make sure we get a signed value first + break; + } + case Instruction::IntToPtr: //always treated as unsigned + case Instruction::UIToFP: + case Instruction::ZExt: + // A ZExt always produces an unsigned value so we need to cast the value + // now before we try to cast it to the destination type + if (isa<ConstantInt>(V)) + V = ConstantInt::get(SrcTy->getUnsignedVersion(), + cast<ConstantIntegral>(V)->getZExtValue()); + break; + case Instruction::SIToFP: + case Instruction::SExt: + // A SExt always produces a signed value so we need to cast the value + // now before we try to cast it to the destiniation type. + if (isa<ConstantInt>(V)) + V = ConstantInt::get(SrcTy->getSignedVersion(), + cast<ConstantIntegral>(V)->getSExtValue()); + break; - if (ElTy == DPTy->getElementType()) - return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V),IdxList); + case Instruction::PtrToInt: + // Cast of a global address to boolean is always true. + if (isa<GlobalValue>(V)) { + if (DestTy == Type::BoolTy) + // FIXME: When we support 'external weak' references, we have to + // prevent this transformation from happening. This code will need + // to be updated to ignore external weak symbols when we support it. + return ConstantBool::getTrue(); } - - // Handle casts from one packed constant to another. We know that the src and - // dest type have the same size. - if (const PackedType *DestPTy = dyn_cast<PackedType>(DestTy)) { - if (const PackedType *SrcTy = dyn_cast<PackedType>(V->getType())) { - assert(DestPTy->getElementType()->getPrimitiveSizeInBits() * - DestPTy->getNumElements() == - SrcTy->getElementType()->getPrimitiveSizeInBits() * - SrcTy->getNumElements() && "Not cast between same sized vectors!"); - if (isa<ConstantAggregateZero>(V)) - return Constant::getNullValue(DestTy); - if (isa<UndefValue>(V)) - return UndefValue::get(DestTy); - if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(V)) { - // This is a cast from a ConstantPacked of one type to a ConstantPacked - // of another type. Check to see if all elements of the input are - // simple. - bool AllSimpleConstants = true; - for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) { - if (!isa<ConstantInt>(CP->getOperand(i)) && - !isa<ConstantFP>(CP->getOperand(i))) { - AllSimpleConstants = false; + break; + case Instruction::BitCast: + // Check to see if we are casting a pointer to an aggregate to a pointer to + // the first element. If so, return the appropriate GEP instruction. + if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) + if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy)) { + std::vector<Value*> IdxList; + IdxList.push_back(Constant::getNullValue(Type::IntTy)); + const Type *ElTy = PTy->getElementType(); + while (ElTy != DPTy->getElementType()) { + if (const StructType *STy = dyn_cast<StructType>(ElTy)) { + if (STy->getNumElements() == 0) break; + ElTy = STy->getElementType(0); + IdxList.push_back(Constant::getNullValue(Type::UIntTy)); + } else if (const SequentialType *STy = + dyn_cast<SequentialType>(ElTy)) { + if (isa<PointerType>(ElTy)) break; // Can't index into pointers! + ElTy = STy->getElementType(); + IdxList.push_back(IdxList[0]); + } else { break; } } - - // If all of the elements are simple constants, we can fold this. - if (AllSimpleConstants) - return CastConstantPacked(const_cast<ConstantPacked*>(CP), DestPTy); + + if (ElTy == DPTy->getElementType()) + return ConstantExpr::getGetElementPtr( + const_cast<Constant*>(V),IdxList); + } + + // Handle casts from one packed constant to another. We know that the src + // and dest type have the same size (otherwise its an illegal cast). + if (const PackedType *DestPTy = dyn_cast<PackedType>(DestTy)) { + if (const PackedType *SrcTy = dyn_cast<PackedType>(V->getType())) { + assert(DestPTy->getBitWidth() == SrcTy->getBitWidth() && + "Not cast between same sized vectors!"); + // First, check for null and undef + if (isa<ConstantAggregateZero>(V)) + return Constant::getNullValue(DestTy); + if (isa<UndefValue>(V)) + return UndefValue::get(DestTy); + + if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(V)) { + // This is a cast from a ConstantPacked of one type to a + // ConstantPacked of another type. Check to see if all elements of + // the input are simple. + bool AllSimpleConstants = true; + for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) { + if (!isa<ConstantInt>(CP->getOperand(i)) && + !isa<ConstantFP>(CP->getOperand(i))) { + AllSimpleConstants = false; + break; + } + } + + // If all of the elements are simple constants, we can fold this. + if (AllSimpleConstants) + return CastConstantPacked(const_cast<ConstantPacked*>(CP), DestPTy); + } } } + + // Handle sign conversion for integer no-op casts. We need to cast the + // value to the correct signedness before we try to cast it to the + // destination type. Be careful to do this only for integer types. + if (isa<ConstantIntegral>(V) && SrcTy->isInteger()) { + if (SrcTy->isSigned()) + V = ConstantInt::get(SrcTy->getUnsignedVersion(), + cast<ConstantIntegral>(V)->getZExtValue()); + else + V = ConstantInt::get(SrcTy->getSignedVersion(), + cast<ConstantIntegral>(V)->getSExtValue()); + } + break; + default: + assert(!"Invalid CE CastInst opcode"); + break; } + // Okay, no more folding possible, time to cast ConstRules &Rules = ConstRules::get(V, V); - switch (DestTy->getTypeID()) { case Type::BoolTyID: return Rules.castToBool(V); case Type::UByteTyID: return Rules.castToUByte(V); @@ -922,6 +995,7 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, case Type::DoubleTyID: return Rules.castToDouble(V); case Type::PointerTyID: return Rules.castToPointer(V, cast<PointerType>(DestTy)); + // what about packed ? default: return 0; } } @@ -1049,15 +1123,22 @@ static bool isMaybeZeroSizedType(const Type *Ty) { static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { if (C1 == C2) return 0; - // Ok, we found a different index. Are either of the operands - // ConstantExprs? If so, we can't do anything with them. + // Ok, we found a different index. Are either of the operands ConstantExprs? + // If so, we can't do anything with them. if (!isa<ConstantInt>(C1) || !isa<ConstantInt>(C2)) return -2; // don't know! // Ok, we have two differing integer indices. Sign extend them to be the same // type. Long is always big enough, so we use it. - C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); - C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); + if (C1->getType() != Type::LongTy && C1->getType() != Type::ULongTy) + C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); + else + C1 = ConstantExpr::getBitCast(C1, Type::LongTy); + if (C2->getType() != Type::LongTy && C1->getType() != Type::ULongTy) + C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); + else + C2 = ConstantExpr::getBitCast(C2, Type::LongTy); + if (C1 == C2) return 0; // Are they just differing types? // If the type being indexed over is really just a zero sized type, there is @@ -1141,7 +1222,19 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { Constant *CE1Op0 = CE1->getOperand(0); switch (CE1->getOpcode()) { - case Instruction::Cast: + case Instruction::Trunc: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::FPToUI: + case Instruction::FPToSI: + break; // We don't do anything with floating point. + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: // If the cast is not actually changing bits, and the second operand is a // null pointer, do the comparison with the pre-casted value. if (V2->isNullValue() && @@ -1154,8 +1247,7 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { // important for things like "seteq (cast 4 to int*), (cast 5 to int*)", // which happens a lot in compilers with tagged integers. if (ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2)) - if (isa<PointerType>(CE1->getType()) && - CE2->getOpcode() == Instruction::Cast && + if (isa<PointerType>(CE1->getType()) && CE2->isCast() && CE1->getOperand(0)->getType() == CE2->getOperand(0)->getType() && CE1->getOperand(0)->getType()->isIntegral()) { return evaluateRelation(CE1->getOperand(0), CE2->getOperand(0)); @@ -1423,8 +1515,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, if (cast<ConstantIntegral>(V2)->isAllOnesValue()) return const_cast<Constant*>(V1); // X & -1 == X if (V2->isNullValue()) return const_cast<Constant*>(V2); // X & 0 == 0 - if (CE1->getOpcode() == Instruction::Cast && - isa<GlobalValue>(CE1->getOperand(0))) { + if (CE1->isCast() && isa<GlobalValue>(CE1->getOperand(0))) { GlobalValue *CPR = cast<GlobalValue>(CE1->getOperand(0)); // Functions are at least 4-byte aligned. If and'ing the address of a @@ -1566,8 +1657,7 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // long 0, long 0) // To: int* getelementptr ([3 x int]* %X, long 0, long 0) // - if (CE->getOpcode() == Instruction::Cast && IdxList.size() > 1 && - Idx0->isNullValue()) + if (CE->isCast() && IdxList.size() > 1 && Idx0->isNullValue()) if (const PointerType *SPT = dyn_cast<PointerType>(CE->getOperand(0)->getType())) if (const ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType())) diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h index 5119aaf3f7..2824979cf4 100644 --- a/lib/VMCore/ConstantFold.h +++ b/lib/VMCore/ConstantFold.h @@ -27,7 +27,11 @@ namespace llvm { class Type; // Constant fold various types of instruction... - Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy); + Constant *ConstantFoldCastInstruction( + unsigned opcode, ///< The opcode of the cast + const Constant *V, ///< The source constant + const Type *DestTy ///< The destination type + ); Constant *ConstantFoldSelectInstruction(const Constant *Cond, const Constant *V1, const Constant *V2); diff --git a/lib/VMCore/ConstantFolding.h b/lib/VMCore/ConstantFolding.h index 5119aaf3f7..2824979cf4 100644 --- a/lib/VMCore/ConstantFolding.h +++ b/lib/VMCore/ConstantFolding.h @@ -27,7 +27,11 @@ namespace llvm { class Type; // Constant fold various types of instruction... - Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy); + Constant *ConstantFoldCastInstruction( + unsigned opcode, ///< The opcode of the cast + const Constant *V, ///< The source constant + const Type *DestTy ///< The destination type + ); Constant *ConstantFoldSelectInstruction(const Constant *Cond, const Constant *V1, const Constant *V2); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index d91e21841d..06dcbb38a7 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -427,6 +427,14 @@ struct VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr { }; } + +// Utility function for determining if a ConstantExpr is a CastOp or not. This +// can't be inline because we don't want to #include Instruction.h into +// Constant.h +bool ConstantExpr::isCast() const { + return Instruction::isCast(getOpcode()); +} + /// ConstantExpr::get* - Return some common constants without having to /// specify the full Instruction::OPCODE identifier. /// @@ -507,8 +515,8 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2) { /// getWithOperandReplaced - Return a constant expression identical to this /// one, but with the specified operand set to the specified value. -Constant *ConstantExpr::getWithOperandReplaced(unsigned OpNo, - Constant *Op) const { +Constant * +ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { assert(OpNo < getNumOperands() && "Operand num is out of range!"); assert(Op->getType() == getOperand(OpNo)->getType() && "Replacing operand with value of different type!"); @@ -517,8 +525,19 @@ Constant *ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op0, *Op1, *Op2; switch (getOpcode()) { - case Instruction::Cast: - return ConstantExpr::getCast(Op, getType()); + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + return ConstantExpr::getCast(getOpcode(), Op, getType()); case Instruction::Select: Op0 = (OpNo == 0) ? Op : getOperand(0); Op1 = (OpNo == 1) ? Op : getOperand(1); @@ -571,8 +590,19 @@ getWithOperands(const std::vector<Constant*> &Ops) const { return const_cast<ConstantExpr*>(this); switch (getOpcode()) { - case Instruction::Cast: - return ConstantExpr::getCast(Ops[0], getType()); + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + return ConstantExpr::getCast(getOpcode(), Ops[0], getType()); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); case Instruction::InsertElement: @@ -1317,8 +1347,8 @@ namespace llvm { template<> struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V) { - if (V.first == Instruction::Cast) - return new UnaryConstantExpr(Instruction::Cast, V.second[0], Ty); + if (Instruction::isCast(V.first)) + return new UnaryConstantExpr(V.first, V.second[0], Ty); if ((V.first >= Instruction::BinaryOpsBegin && V.first < Instruction::BinaryOpsEnd) || V.first == Instruction::Shl || @@ -1348,8 +1378,20 @@ namespace llvm { static void convert(ConstantExpr *OldC, const Type *NewTy) { Constant *New; switch (OldC->getOpcode()) { - case Instruction::Cast: - New = ConstantExpr::getCast(OldC->getOperand(0), NewTy); + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + New = ConstantExpr::getCast( + OldC->getOpcode(), OldC->getOperand(0), NewTy); break; case Instruction::Select: New = ConstantExpr::getSelectTy(NewTy, OldC->getOperand(0), @@ -1394,40 +1436,143 @@ static ExprMapKeyType getValType(ConstantExpr *CE) { static ManagedStatic<ValueMap<ExprMapKeyType, Type, ConstantExpr> > ExprConstants; -Constant *ConstantExpr::getCast(Constant *C, const Type *Ty) { +/// This is a utility function to handle folding of casts and lookup of the +/// cast in the ExprConstants map. It is usedby the various get* methods below. +static inline Constant *getFoldedCast( + Instruction::CastOps opc, Constant *C, const Type *Ty) { assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!"); - - if (Constant *FC = ConstantFoldCastInstruction(C, Ty)) - return FC; // Fold a few common cases... + // Fold a few common cases + if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty)) + return FC; // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> argVec(1, C); - ExprMapKeyType Key = std::make_pair(Instruction::Cast, argVec); + ExprMapKeyType Key = std::make_pair(opc, argVec); return ExprConstants->getOrCreate(Ty, Key); } -Constant *ConstantExpr::getSignExtend(Constant *C, const Type *Ty) { - assert(C->getType()->isIntegral() && Ty->isIntegral() && - C->getType()->getPrimitiveSize() <= Ty->getPrimitiveSize() && - "This is an illegal sign extension!"); - if (C->getType() != Type::BoolTy) { - C = ConstantExpr::getCast(C, C->getType()->getSignedVersion()); - return ConstantExpr::getCast(C, Ty); - } else { - if (C == ConstantBool::getTrue()) - return ConstantIntegral::getAllOnesValue(Ty); - else - return ConstantIntegral::getNullValue(Ty); +Constant *ConstantExpr::getCast( Constant *C, const Type *Ty ) { + // Note: we can't inline this because it requires the Instructions.h header + return getCast(CastInst::getCastOpcode(C, Ty), C, Ty); +} + +Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { + Instruction::CastOps opc = Instruction::CastOps(oc); + assert(Instruction::isCast(opc) && "opcode out of range"); + assert(C && Ty && "Null arguments to getCast"); + assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!"); + + switch (opc) { + default: + assert(0 && "Invalid cast opcode"); + break; + case Instruction::Trunc: return getTrunc(C, Ty); + case Instruction::ZExt: return getZeroExtend(C, Ty); + case Instruction::SExt: return getSignExtend(C, Ty); + case Instruction::FPTrunc: return getFPTrunc(C, Ty); + case Instruction::FPExt: return getFPExtend(C, Ty); + case Instruction::UIToFP: return getUIToFP(C, Ty); + case Instruction::SIToFP: return getSIToFP(C, Ty); + case Instruction::FPToUI: return getFPToUI(C, Ty); + case Instruction::FPToSI: return getFPToSI(C, Ty); + case Instruction::PtrToInt: return getPtrToInt(C, Ty); + case Instruction::IntToPtr: return getIntToPtr(C, Ty); + case Instruction::BitCast: return getBitCast(C, Ty); } + return 0; +} + +Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) { + assert(C->getType()->isInteger() && "Trunc operand must be integer"); + assert(Ty->isIntegral() && "Trunc produces only integral"); + assert(C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&& + "SrcTy must be larger than DestTy for Trunc!"); + + return getFoldedCast(Instruction::Trunc, C, Ty); +} + +Constant *ConstantExpr::getSignExtend(Constant *C, const Type *Ty) { + assert(C->getType()->isIntegral() && "SEXt operand must be integral"); + assert(Ty->isInteger() && "SExt produces only integer"); + assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&& + "SrcTy must be smaller than DestTy for SExt!"); + + return getFoldedCast(Instruction::SExt, C, Ty); } Constant *ConstantExpr::getZeroExtend(Constant *C, const Type *Ty) { - assert(C->getType()->isIntegral() && Ty->isIntegral() && - C->getType()->getPrimitiveSize() <= Ty->getPrimitiveSize() && - "This is an illegal zero extension!"); - if (C->getType() != Type::BoolTy) - C = ConstantExpr::getCast(C, C->getType()->getUnsignedVersion()); - return ConstantExpr::getCast(C, Ty); + assert(C->getType()->isIntegral() && "ZEXt operand must be integral"); + assert(Ty->isInteger() && "ZExt produces only integer"); + assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&& + "SrcTy must be smaller than DestTy for ZExt!"); + + return getFoldedCast(Instruction::ZExt, C, Ty); +} + +Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) { + assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && + C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&& + "This is an illegal floating point truncation!"); + return getFoldedCast(Instruction::FPTrunc, C, Ty); +} + +Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) { + assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && + C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&& + "This is an illegal floating point extension!"); + return getFoldedCast(Instruction::FPExt, C, Ty); +} + +Constant *ConstantExpr::getUIToFP(Constant *C, const Type *Ty) { + assert(C->getType()->isIntegral() && Ty->isFloatingPoint() && + "This is an illegal uint to floating point cast!"); + return getFoldedCast(Instruction::UIToFP, C, Ty); +} + +Constant *ConstantExpr::getSIToFP(Constant *C, const Type *Ty) { + assert(C->getType()->isIntegral() && Ty->isFloatingPoint() && + "This is an illegal sint to floating point cast!"); + return getFoldedCast(Instruction::SIToFP, C, Ty); +} + +Constant *ConstantExpr::getFPToUI(Constant *C, const Type *Ty) { + assert(C->getType()->isFloatingPoint() && Ty->isIntegral() && + "This is an illegal floating point to uint cast!"); + return getFoldedCast(Instruction::FPToUI, C, Ty); +} + +Constant *ConstantExpr::getFPToSI(Constant *C, const Type *Ty) { + assert(C->getType()->isFloatingPoint() && Ty->isIntegral() && + "This is an illegal floating point to sint cast!"); + return getFoldedCast(Instruction::FPToSI, C, Ty); +} + +Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) { + assert(isa<PointerType>(C->getType()) && "PtrToInt source must be pointer"); + assert(DstTy->isIntegral() && "PtrToInt destination must be integral"); + return getFoldedCast(Instruction::PtrToInt, C, DstTy); +} + +Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) { + assert(C->getType()->isIntegral() && "IntToPtr source must be integral"); + assert(isa<PointerType>(DstTy) && "IntToPtr destination must be a pointer"); + return getFoldedCast(Instruction::IntToPtr, C, DstTy); +} + +Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { + // BitCast implies a no-op cast of type only. No bits change. However, you + // can't cast pointers to anything but pointers. + const Type *SrcTy = C->getType(); + assert((isa<PointerType>(SrcTy) == isa<PointerType>(DstTy)) && + "Bitcast cannot cast pointer to non-pointer and vice versa"); + + // Now we know we're not dealing with mismatched pointer casts (ptr->nonptr + // or nonptr->ptr). For all the other types, the cast is okay if source and + // destination bit widths are identical. + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DstBitSize = DstTy->getPrimitiveSizeInBits(); + assert(SrcBitSize == DstBitSize && "Bitcast requies types of same width"); + return getFoldedCast(Instruction::BitCast, C, DstTy); } Constant *ConstantExpr::getSizeOf(const Type *Ty) { @@ -1858,9 +2003,9 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, Indices.push_back(Val); } Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices); - } else if (getOpcode() == Instruction::Cast) { + } else if (isCast()) { assert(getOperand(0) == From && "Cast only has one use!"); - Replacement = ConstantExpr::getCast(To, getType()); + Replacement = ConstantExpr::getCast(getOpcode(), To, getType()); } else if (getOpcode() == Instruction::Select) { Constant *C1 = getOperand(0); Constant *C2 = getOperand(1); diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 641cb9fe7e..7a44ec0786 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -226,7 +226,7 @@ const char *Intrinsic::getName(ID id) { Value *IntrinsicInst::StripPointerCasts(Value *Ptr) { if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) { - if (CE->getOpcode() == Instruction::Cast) { + if (CE->getOpcode() == Instruction::BitCast) { if (isa<PointerType>(CE->getOperand(0)->getType())) return StripPointerCasts(CE->getOperand(0)); } else if (CE->getOpcode() == Instruction::GetElementPtr) { @@ -238,7 +238,7 @@ Value *IntrinsicInst::StripPointerCasts(Value *Ptr) { return Ptr; } - if (CastInst *CI = dyn_cast<CastInst>(Ptr)) { + if (BitCastInst *CI = dyn_cast<BitCastInst>(Ptr)) { if (isa<PointerType>(CI->getOperand(0)->getType())) return StripPointerCasts(CI->getOperand(0)); } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr)) { diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 64a9e12f82..5c741f7b87 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -122,18 +122,31 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Store: return "store"; case GetElementPtr: return "getelementptr"; + // Convert instructions... + case Trunc: return "trunc"; + case ZExt: return "zext"; + case SExt: return "sext"; + case FPTrunc: return "fptrunc"; + case FPExt: return "fpext"; + case FPToUI: return "fptoui"; + case FPToSI: return "fptosi"; + case UIToFP: return "uitofp"; + case SIToFP: return "sitofp"; + case IntToPtr: return "inttoptr"; + case PtrToInt: return "ptrtoint"; + case BitCast: return "bitcast"; + // Other instructions... - case PHI: return "phi"; - case Cast: return "cast"; - case Select: return "select"; - case Call: return "call"; - case Shl: return "shl"; - case LShr: return "lshr"; - case AShr: return "ashr"; - case VAArg: return "va_arg"; + case PHI: return "phi"; + case Select: return "select"; + case Call: return "call"; + case Shl: return "shl"; + case LShr: return "lshr"; + case AShr: return "ashr"; + case VAArg: return "va_arg"; case ExtractElement: return "extractelement"; - case InsertElement: return "insertelement"; - case ShuffleVector: return "shufflevector"; + case InsertElement: return "insertelement"; + case ShuffleVector: return "shufflevector"; default: return "<Invalid operator> "; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index f559c6324e..d421adb291 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1226,18 +1226,571 @@ bool BinaryOperator::swapOperands() { // CastInst Class //===----------------------------------------------------------------------===// -/// isTruncIntCast - Return true if this is a truncating integer cast -/// instruction, e.g. a cast from long to uint. -bool CastInst::isTruncIntCast() const { - // The dest type has to be integral, the input has to be integer. - if (!getType()->isIntegral() || !getOperand(0)->getType()->isInteger()) +// Just determine if this cast only deals with integral->integral conversion. +bool CastInst::isIntegerCast() const { + switch (getOpcode()) { + default: return false; + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::Trunc: + return true; + case Instruction::BitCast: + return getOperand(0)->getType()->isIntegral() && getType()->isIntegral(); + } +} + +bool CastInst::isLosslessCast() const { + // Only BitCast can be lossless, exit fast if we're not BitCast + if (getOpcode() != Instruction::BitCast) return false; - // Has to be large to smaller. - return getOperand(0)->getType()->getPrimitiveSizeInBits() > - getType()->getPrimitiveSizeInBits(); + // Identity cast is always lossless + const Type* SrcTy = getOperand(0)->getType(); + const Type* DstTy = getType(); + if (SrcTy == DstTy) + return true; + + // The remaining possibilities are lossless if the typeID of the source type + // matches the type ID of the destination in size and fundamental type. This + // prevents things like int -> ptr, int -> float, packed -> int, mismatched + // packed types of the same size, and etc. + switch (SrcTy->getTypeID()) { + case Type::UByteTyID: return DstTy == Type::SByteTy; + case Type::SByteTyID: return DstTy == Type::UByteTy; + case Type::UShortTyID: return DstTy == Type::ShortTy; + case Type::ShortTyID: return DstTy == Type::UShortTy; + case Type::UIntTyID: return DstTy == Type::IntTy; + case Type::IntTyID: return DstTy == Type::UIntTy; + case Type::ULongTyID: return DstTy == Type::LongTy; + case Type::LongTyID: return DstTy == Type::ULongTy; + case Type::PointerTyID: return isa<PointerType>(DstTy); + default: + break; + } + return false; // Other types have no identity values +} + +/// This function determines if the CastInst does not require any bits to be +/// changed in order to effect the cast. Essentially, it identifies cases where +/// no code gen is necessary for the cast, hence the name no-op cast. For +/// example, the following are all no-op casts: +/// # bitcast uint %X, int +/// # bitcast uint* %x, sbyte* +/// # bitcast packed< 2 x int > %x, packed< 4 x short> +/// # ptrtoint uint* %x, uint ; on 32-bit plaforms only +/// @brief Determine if a cast is a no-op. +bool CastInst::isNoopCast(const Type *IntPtrTy) const { + switch (getOpcode()) { + default: + assert(!"Invalid CastOp"); + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + return false; // These always modify bits + case Instruction::BitCast: + return true; // BitCast never modifies bits. + case Instruction::PtrToInt: + return IntPtrTy->getPrimitiveSizeInBits() == + getType()->getPrimitiveSizeInBits(); + case Instruction::IntToPtr: + return IntPtrTy->getPrimitiveSizeInBits() == + getOperand(0)->getType()->getPrimitiveSizeInBits(); + } +} + +/// This function determines if a pair of casts can be eliminated and what +/// opcode should be used in the elimination. This assumes that there are two +/// instructions like this: +/// * %F = firstOpcode SrcTy %x to MidTy +/// * %S = secondOpcode MidTy %F to DstTy +/// The function returns a resultOpcode so these two casts can be replaced with: +/// * %Replacement = resultOpcode %SrcTy %x to DstTy +/// If no such cast is permited, the function returns 0. +unsigned CastInst::isEliminableCastPair( + Instruction::CastOps firstOp, Instruction::CastOps secondOp, + const Type *SrcTy, const Type *MidTy, const Type *DstTy, const Type *IntPtrTy) +{ + // Define the 144 possibilities for these two cast instructions. The values + // in this matrix determine what to do in a given situation and select the + // case in the switch below. The rows correspond to firstOp, the columns + // correspond to secondOp. In looking at the table below, keep in mind + // the following cast properties: + // + // Size Compare Source Destination + // Operator Src ? Size Type Sign Type Sign + // -------- ------------ ------------------- --------------------- + // TRUNC > Integer Any Integral Any + // ZEXT < Integral Unsigned Integer Any + // SEXT < Integral Signed Integer Any + // FPTOUI n/a FloatPt n/a Integral Unsigned + // FPTOSI n/a FloatPt n/a Integral Signed + // UITOFP n/a Integral Unsigned FloatPt n/a + // SITOFP n/a Integral Signed FloatPt n/a + // FPTRUNC > FloatPt n/a FloatPt n/a + // FPEXT < FloatPt n/a FloatPt n/a + // PTRTOINT n/a Pointer n/a Integral Unsigned + // INTTOPTR n/a Integral Unsigned Pointer n/a + // BITCONVERT = FirstClass n/a FirstClass n/a + // + const unsigned numCastOps = + Instruction::CastOpsEnd - Instruction::CastOpsBegin; + static const uint8_t CastResults[numCastOps][numCastOps] = { + // T F F U S F F P I B -+ + // R Z S P P I I T P 2 N T | + // U E E 2 2 2 2 R E I T C +- secondOp + // N X X U S F F N X N 2 V | + // C T T I I P P C T T P T -+ + { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3 }, // Trunc -+ + { 8, 1, 9,99,99, 2, 0,99,99,99, 2, 3 }, // ZExt | + { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3 }, // SExt | + { 0, 1, 0,99,99, 0, 0,99,99,99, 0, 3 }, // FPToUI | + { 0, 0, 1,99,99, 0, 0,99,99,99, 0, 3 }, // FPToSI | + { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // UIToFP +- firstOp + { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4 }, // SIToFP | + { 99,99,99, 0, 0,99,99, 1, 0,99,99, 4 }, // FPTrunc | + { 99,99,99, 2, 2,99,99,10, 2,99,99, 4 }, // FPExt | + { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3 }, // PtrToInt | + { 99,99,99,99,99,99,99,99,99,13,99,12 }, // IntToPtr | + { 5, 5, 5, 6, 6, 5, 5, 6, 6,11, 5, 1 }, // BitCast -+ + }; + + int ElimCase = CastResults[firstOp-Instruction::CastOpsBegin] + [secondOp-Instruction::CastOpsBegin]; + switch (ElimCase) { + case 0: + // categorically disallowed + return 0; + case 1: + // allowed, use first cast's opcode + return firstOp; + case 2: + // allowed, use second cast's opcode + return secondOp; + case 3: + // no-op cast in second op implies firstOp as long as the DestTy + // is integer + if (DstTy->isInteger()) + return firstOp; + return 0; + case 4: + // no-op cast in second op implies firstOp as long as the DestTy + // is floating point + if (DstTy->isFloatingPoint()) + return firstOp; + return 0; + case 5: + // no-op cast in first op implies secondOp as long as the SrcTy + // is an integer + if (SrcTy->isInteger()) + return secondOp; + return 0; + case 6: + // no-op cast in first op implies secondOp as long as the SrcTy + // is a floating point + if (SrcTy->isFloatingPoint()) + return secondOp; + return 0; + case 7: { + // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size + unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits(); + unsigned MidSize = MidTy->getPrimitiveSizeInBits(); + if (MidSize >= PtrSize) + return Instruction::BitCast; + return 0; + } + case 8: { + // ext, trunc -> bitcast, if the SrcTy and DstTy are same size + // ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy) + // ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy) + unsigned SrcSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DstSize = DstTy->getPrimitiveSizeInBits(); + if (SrcSize == DstSize) + return Instruction::BitCast; + else if (SrcSize < DstSize) + return firstOp; + return secondOp; + } + case 9: // zext, sext -> zext, because sext can't sign extend after zext + return Instruction::ZExt; + case 10: + // fpext followed by ftrunc is allowed if the bit size returned to is + // the same as the original, in which case its just a bitcast + if (SrcTy == DstTy) + return Instruction::BitCast; + return 0; // If the types are not the same we can't eliminate it. + case 11: + // bitcast followed by ptrtoint is allowed as long as the bitcast + // is a pointer to pointer cast. + if (isa<PointerType>(SrcTy) && isa<PointerType>(MidTy)) + return secondOp; + return 0; + case 12: + // inttoptr, bitcast -> intptr if bitcast is a ptr to ptr cast + if (isa<PointerType>(MidTy) && isa<PointerType>(DstTy)) + return firstOp; + return 0; + case 13: { + // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize + unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits(); + unsigned SrcSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DstSize = DstTy->getPrimitiveSizeInBits(); + if (SrcSize <= PtrSize && SrcSize == DstSize) + return Instruction::BitCast; + return 0; + } + case 99: + // cast combination can't happen (error in input). This is for all cases + // where the MidTy is not the same for the two cast instructions. + assert(!"Invalid Cast Combination"); + return 0; + default: + assert(!"Error in CastResults table!!!"); + return 0; + } + return 0; +} + +CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty, + const std::string &Name, Instruction *InsertBefore) { + // Construct and return the appropriate CastInst subclass + switch (op) { + case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); + case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore); + case SExt: return new SExtInst (S, Ty, Name, InsertBefore); + case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore); + case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore); + case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore); + case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore); + case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore); + case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore); + case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); + case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); + case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore); + default: + assert(!"Invalid opcode provided"); + } + return 0; } +CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty, + const std::string &Name, BasicBlock *InsertAtEnd) { + // Construct and return the appropriate CastInst subclass + switch (op) { + case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); + case ZExt: return new ZExtInst (S, Ty, Name, InsertAtEnd); + case SExt: return new SExtInst (S, Ty, Name, InsertAtEnd); + case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertAtEnd); + case FPExt: return new FPExtInst (S, Ty, Name, InsertAtEnd); + case UIToFP: return new UIToFPInst (S, Ty, Name, InsertAtEnd); + case SIToFP: return new SIToFPInst (S, Ty, Name, InsertAtEnd); + case FPToUI: return new FPToUIInst (S, Ty, Name, InsertAtEnd); + case FPToSI: return new FPToSIInst (S, Ty, Name, InsertAtEnd); + case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); + case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); + case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd); + default: + assert(!"Invalid opcode provided"); + } + return 0; +} + +// Provide a way to get a "cast" where the cast opcode is inferred from the +// types and size of the operand. This, basically, is a parallel of the +// logic in the checkCast function below. This axiom should hold: +// checkCast( getCastOpcode(Val, Ty), Val, Ty) +// should not assert in checkCast. In other words, this produces a "correct" +// casting opcode for the arguments passed to it. +Instruction::CastOps +CastInst::getCastOpcode(const Value *Src, const Type *DestTy) { + // Get the bit sizes, we'll need these + const Type *SrcTy = Src->getType(); + unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/packed + unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/packed + + // Run through the possibilities ... + if (DestTy->isIntegral()) { // Casting to integral + if (SrcTy->isIntegral()) { // Casting from integral + if (DestBits < SrcBits) + return Trunc; // int -> smaller int + else if (DestBits > SrcBits) { // its an extension + if (SrcTy->isSigned()) + return SExt; // signed -> SEXT + else + return ZExt; // unsigned -> ZEXT + } else { + return BitCast; // Same size, No-op cast + } + } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt + if (DestTy->isSigned()) + return FPToSI; // FP -> sint + else + return FPToUI; // FP -> uint + } else if (const PackedType *PTy = dyn_cast<PackedType>(SrcTy)) { + assert(DestBits == PTy->getBitWidth() && + "Casting packed to integer of different width"); + return BitCast; // Same size, no-op cast + } else { + assert(isa<PointerType>(SrcTy) && + "Casting from a value that is not first-class type"); + return PtrToInt; // ptr -> int + } + } else if (DestTy->isFloatingPoint()) { // Casting to floating pt + if (SrcTy->isIntegral()) { // Casting from integral + if (SrcTy->isSigned()) + return SIToFP; // sint -> FP + else + return UIToFP; // uint -> FP + } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt + if (DestBits < SrcBits) { + return FPTrunc; // FP -> smaller FP + } else if (DestBits > SrcBits) { + return FPExt; // FP -> larger FP + } else { + return BitCast; // same size, no-op cast + } + } else if (const PackedType *PTy = dyn_cast<PackedType>(SrcTy)) { + assert(DestBits == PTy->getBitWidth() && + "Casting packed to floating point of different width"); + return BitCast; // same size, no-op cast + } else { + assert(0 && "Casting pointer or non-first class to float"); + } + } else if (const PackedType *DestPTy = dyn_cast<PackedType>(DestTy)) { + if (const PackedType *SrcPTy = dyn_cast<PackedType>(SrcTy)) { + assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() && + "Casting packed to packed of different widths"); + return BitCast; // packed -> packed + } else if (DestPTy->getBitWidth() == SrcBits) { + return BitCast; // float/int -> packed + } else { + assert(!"Illegal cast to packed (wrong type or size)"); + } + } else if (isa<PointerType>(DestTy)) { + if (isa<PointerType>(SrcTy)) { + return BitCast; // ptr -> ptr + } else if (SrcTy->isIntegral()) { + return IntToPtr; // int -> ptr + } else { + assert(!"Casting pointer to other than pointer or int"); + } + } else { + assert(!"Casting to type that is not first-class"); + } + + // If we fall through to here we probably hit an assertion cast above + // and assertions are not turned on. Anything we return is an error, so + // BitCast is as good a choice as any. + return BitCast; +} + +//===----------------------------------------------------------------------===// +// CastInst SubClass Constructors +//===----------------------------------------------------------------------===// + +/// Check that the construction parameters for a CastInst are correct. This +/// could be broken out into the separate constructors but it is useful to have +/// it in one place and to eliminate the redundant code for getting the sizes +/// of the types involved. +static bool +checkCast(Instruction::CastOps op, Value *S, const Type *DstTy) { + + // Check for type sanity on the arguments + const Type *SrcTy = S->getType(); + if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType()) + return false; + + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DstBitSize = DstTy->getPrimitiveSizeInBits(); + + // Switch on the opcode provided + switch (op) { + default: return false; // This is an input error + case Instruction::Trunc: + return SrcTy->isInteger() && DstTy->isIntegral() && SrcBitSize > DstBitSize; + case Instruction::ZExt: + return SrcTy->isIntegral() && DstTy->isInteger() && SrcBitSize < DstBitSize; + case Instruction::SExt: + return SrcTy->isIntegral() && DstTy->isInteger() && SrcBitSize < DstBitSize; + case Instruction::FPTrunc: + return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && + SrcBitSize > DstBitSize; + case Instruction::FPExt: + return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && + SrcBitSize < DstBitSize; + case Instruction::UIToFP: + return SrcTy->isIntegral() && DstTy->isFloatingPoint(); + case Instruction::SIToFP: + return SrcTy->isIntegral() && DstTy->isFloatingPoint(); + case Instruction::FPToUI: + return SrcTy->isFloatingPoint() && DstTy->isIntegral(); + case Instruction::FPToSI: + return SrcTy->isFloatingPoint() && DstTy->isIntegral(); + case Instruction::PtrToInt: + return isa<PointerType>(SrcTy) && DstTy->isIntegral(); + case Instruction::IntToPtr: + return SrcTy->isIntegral() && isa<PointerType>(DstTy); + case Instruction::BitCast: + // BitCast implies a no-op cast of type only. No bits change. + // However, you can't cast pointers to anything but pointers. + if (isa<PointerType>(SrcTy) != isa<PointerType>(DstTy)) + return false; + + // Now we know we're not dealing with a pointer/non-poiner mismatch. In all + // these cases, the cast is okay if the source and destination bit widths + // are identical. + return SrcBitSize == DstBitSize; + } +} + +TruncInst::TruncInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, Trunc, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal Trunc"); +} + +TruncInst::TruncInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, Trunc, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal Trunc"); +} + +ZExtInst::ZExtInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, ZExt, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal ZExt"); +} + +ZExtInst::ZExtInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, ZExt, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal ZExt"); +} +SExtInst::SExtInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, SExt, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal SExt"); +} + +SExtInst::SExtInst::SExtInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, SExt, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal SExt"); +} + +FPTruncInst::FPTruncInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, FPTrunc, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPTrunc"); +} + +FPTruncInst::FPTruncInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, FPTrunc, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPTrunc"); +} + +FPExtInst::FPExtInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, FPExt, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPExt"); +} + +FPExtInst::FPExtInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, FPExt, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPExt"); +} + +UIToFPInst::UIToFPInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, UIToFP, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal UIToFP"); +} + +UIToFPInst::UIToFPInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, UIToFP, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal UIToFP"); +} + +SIToFPInst::SIToFPInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, SIToFP, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal SIToFP"); +} + +SIToFPInst::SIToFPInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, SIToFP, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal SIToFP"); +} + +FPToUIInst::FPToUIInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, FPToUI, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToUI"); +} + +FPToUIInst::FPToUIInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, FPToUI, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToUI"); +} + +FPToSIInst::FPToSIInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, FPToSI, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToSI"); +} + +FPToSIInst::FPToSIInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, FPToSI, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal FPToSI"); +} + +PtrToIntInst::PtrToIntInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, PtrToInt, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal PtrToInt"); +} + +PtrToIntInst::PtrToIntInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, PtrToInt, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal PtrToInt"); +} + +IntToPtrInst::IntToPtrInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal IntToPtr"); +} + +IntToPtrInst::IntToPtrInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, IntToPtr, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal IntToPtr"); +} + +BitCastInst::BitCastInst( + Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore +) : CastInst(Ty, BitCast, S, Name, InsertBefore) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal BitCast"); +} + +BitCastInst::BitCastInst( + Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd +) : CastInst(Ty, BitCast, S, Name, InsertAtEnd) { + assert(checkCast(getOpcode(), S, Ty) && "Illegal BitCast"); +} //===----------------------------------------------------------------------===// // SetCondInst Class @@ -1608,16 +2161,28 @@ CmpInst* CmpInst::clone() const { Ops[0], Ops[1]); } -MallocInst *MallocInst::clone() const { return new MallocInst(*this); } -AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); } -FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); } -LoadInst *LoadInst::clone() const { return new LoadInst(*this); } -StoreInst *StoreInst::clone() const { return new StoreInst(*this); } -CastInst *CastInst::clone() const { return new CastInst(*this); } -CallInst *CallInst::clone() const { return new CallInst(*this); } -ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); } -SelectInst *SelectInst::clone() const { return new SelectInst(*this); } -VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); } +MallocInst *MallocInst::clone() const { return new MallocInst(*this); } +AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); } +FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); } +LoadInst *LoadInst::clone() const { return new LoadInst(*this); } +StoreInst *StoreInst::clone() const { return new StoreInst(*this); } +CastInst *TruncInst::clone() const { return new TruncInst(*this); } +CastInst *ZExtInst::clone() const { return new ZExtInst(*this); } +CastInst *SExtInst::clone() const { return new SExtInst(*this); } +CastInst *FPTruncInst::clone() const { return new FPTruncInst(*this); } +CastInst *FPExtInst::clone() const { return new FPExtInst(*this); } +CastInst *UIToFPInst::clone() const { return new UIToFPInst(*this); } +CastInst *SIToFPInst::clone() const { return new SIToFPInst(*this); } +CastInst *FPToUIInst::clone() const { return new FPToUIInst(*this); } +CastInst *FPToSIInst::clone() const { return new FPToSIInst(*this); } +CastInst *PtrToIntInst::clone() const { return new PtrToIntInst(*this); } +CastInst *IntToPtrInst::clone() const { return new IntToPtrInst(*this); } +CastInst *BitCastInst::clone() const { return new BitCastInst(*this); } +CallInst *CallInst::clone() const { return new CallInst(*this); } +ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); } +SelectInst *SelectInst::clone() const { return new SelectInst(*this); } +VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); } + ExtractElementInst *ExtractElementInst::clone() const { return new ExtractElementInst(*this); } diff --git a/lib/VMCore/IntrinsicInst.cpp b/lib/VMCore/IntrinsicInst.cpp index 5c43b6f5e1..84addcc0aa 100644 --- a/lib/VMCore/IntrinsicInst.cpp +++ b/lib/VMCore/IntrinsicInst.cpp @@ -37,7 +37,7 @@ using namespace llvm; static Value *CastOperand(Value *C) { if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) return CE->getOperand(0); return NULL; } diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index fa948aaefa..ca8149e402 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -98,24 +98,27 @@ bool Type::isFPOrFPVector() const { return cast<PackedType>(this)->getElementType()->isFloatingPoint(); } - -// isLosslesslyConvertibleTo - Return true if this type can be converted to +// canLosslesllyBitCastTo - Return true if this type can be converted to // 'Ty' without any reinterpretation of bits. For example, uint to int. // -bool Type::isLosslesslyConvertibleTo(const Type *Ty) const { - if (this == Ty) return true; - - // Packed type conversions are always bitwise. - if (isa<PackedType>(this) && isa<PackedType>(Ty)) +bool Type::canLosslesslyBitCastTo(const Type *Ty) const { + // Identity cast means no change so return true + if (this == Ty) return true; - if ((!isPrimitiveType() && !isa<PointerType>(this)) || - (!isa<PointerType>(Ty) && !Ty->isPrimitiveType())) return false; + // They are not convertible unless they are at least first class types + if (!this->isFirstClassType() || !Ty->isFirstClassType()) + return false; - if (getTypeID() == Ty->getTypeID()) - return true; // Handles identity cast, and cast of differing pointer types + // Packed -> Packed conversions are always lossless if the two packed types + // have the same size, otherwise not. + if (const PackedType *thisPTy = dyn_cast<PackedType>(this)) + if (const PackedType *thatPTy = dyn_cast<PackedType>(Ty)) + return thisPTy->getBitWidth() == thatPTy->getBitWidth(); - // Now we know that they are two differing primitive or pointer types + // At this point we have only various mismatches of the first class types + // remaining and ptr->ptr. Just select the lossless conversions. Everything + // else is not lossless. switch (getTypeID()) { case Type::UByteTyID: return Ty == Type::SByteTy; case Type::SByteTyID: return Ty == Type::UByteTy; @@ -127,8 +130,9 @@ bool Type::isLosslesslyConvertibleTo(const Type *Ty) const { case Type::LongTyID: return Ty == Type::ULongTy; case Type::PointerTyID: return isa<PointerType>(Ty); default: - return false; // Other types have no identity values + break; } + return false; // Other types have no identity values } /// getUnsignedVersion - If this is an integer type, return the unsigned @@ -200,6 +204,10 @@ unsigned Type::getPrimitiveSizeInBits() const { case Type::LongTyID: case Type::ULongTyID: case Type::DoubleTyID: return 64; + case Type::PackedTyID: { + const PackedType *PTy = cast<PackedType>(this); + return PTy->getBitWidth(); + } default: return 0; } } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 065ac3b775..d57cd51596 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -177,6 +177,18 @@ namespace { // Anonymous namespace for class void visitGlobalVariable(GlobalVariable &GV); void visitFunction(Function &F); void visitBasicBlock(BasicBlock &BB); + void visitTruncInst(TruncInst &I); + void visitZExtInst(ZExtInst &I); + void visitSExtInst(SExtInst &I); + void visitFPTruncInst(FPTruncInst &I); + void visitFPExtInst(FPExtInst &I); + void visitFPToUIInst(FPToUIInst &I); + void visitFPToSIInst(FPToSIInst &I); + void visitUIToFPInst(UIToFPInst &I); + void visitSIToFPInst(SIToFPInst &I); + void visitIntToPtrInst(IntToPtrInst &I); + void visitPtrToIntInst(PtrToIntInst &I); + void visitBitCastInst(BitCastInst &I); void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); void visitICmpInst(ICmpInst &IC); @@ -467,6 +479,169 @@ void Verifier::visitUserOp1(Instruction &I) { Assert1(0, "User-defined operators should not live outside of a pass!", &I); } +void Verifier::visitTruncInst(TruncInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + Assert1(SrcTy->isIntegral(), "Trunc only operates on integer", &I); + Assert1(DestTy->isIntegral(),"Trunc only produces integral", &I); + Assert1(SrcBitSize > DestBitSize,"DestTy too big for Trunc", &I); + + visitInstruction(I); +} + +void Verifier::visitZExtInst(ZExtInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + Assert1(SrcTy->isIntegral(),"ZExt only operates on integral", &I); + Assert1(DestTy->isInteger(),"ZExt only produces an integer", &I); + Assert1(SrcBitSize < DestBitSize,"Type too small for ZExt", &I); + + visitInstruction(I); +} + +void Verifier::visitSExtInst(SExtInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + Assert1(SrcTy->isIntegral(),"SExt only operates on integral", &I); + Assert1(DestTy->isInteger(),"SExt only produces an integer", &I); + Assert1(SrcBitSize < DestBitSize,"Type too small for SExt", &I); + + visitInstruction(I); +} + +void Verifier::visitFPTruncInst(FPTruncInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + Assert1(SrcTy->isFloatingPoint(),"FPTrunc only operates on FP", &I); + Assert1(DestTy->isFloatingPoint(),"FPTrunc only produces an FP", &I); + Assert1(SrcBitSize > DestBitSize,"DestTy too big for FPTrunc", &I); + + visitInstruction(I); +} + +void Verifier::visitFPExtInst(FPExtInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + Assert1(SrcTy->isFloatingPoint(),"FPExt only operates on FP", &I); + Assert1(DestTy->isFloatingPoint(),"FPExt only produces an FP", &I); + Assert1(SrcBitSize < DestBitSize,"DestTy too small for FPExt", &I); + + visitInstruction(I); +} + +void Verifier::visitUIToFPInst(UIToFPInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + Assert1(SrcTy->isIntegral(),"UInt2FP source must be integral", &I); + Assert1(DestTy->isFloatingPoint(),"UInt2FP result must be FP", &I); + + visitInstruction(I); +} + +void Verifier::visitSIToFPInst(SIToFPInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + Assert1(SrcTy->isIntegral(),"SInt2FP source must be integral", &I); + Assert1(DestTy->isFloatingPoint(),"SInt2FP result must be FP", &I); + + visitInstruction(I); +} + +void Verifier::visitFPToUIInst(FPToUIInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + Assert1(SrcTy->isFloatingPoint(),"FP2UInt source must be FP", &I); + Assert1(DestTy->isIntegral(),"FP2UInt result must be integral", &I); + + visitInstruction(I); +} + +void Verifier::visitFPToSIInst(FPToSIInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + Assert1(SrcTy->isFloatingPoint(),"FPToSI source must be FP", &I); + Assert1(DestTy->isIntegral(),"FP2ToI result must be integral", &I); + + visitInstruction(I); +} + +void Verifier::visitPtrToIntInst(PtrToIntInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + Assert1(isa<PointerType>(SrcTy), "PtrToInt source must be pointer", &I); + Assert1(DestTy->isIntegral(), "PtrToInt result must be integral", &I); + + visitInstruction(I); +} + +void Verifier::visitIntToPtrInst(IntToPtrInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + Assert1(SrcTy->isIntegral(), "IntToPtr source must be an integral", &I); + Assert1(isa<PointerType>(DestTy), "IntToPtr result must be a pointer",&I); + + visitInstruction(I); +} + +void Verifier::visitBitCastInst(BitCastInst &I) { + // Get the source and destination types + const Type *SrcTy = I.getOperand(0)->getType(); + const Type *DestTy = I.getType(); + + // Get the size of the types in bits, we'll need this later + unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + + // BitCast implies a no-op cast of type only. No bits change. + // However, you can't cast pointers to anything but pointers. + Assert1(isa<PointerType>(DestTy) == isa<PointerType>(DestTy), + "Bitcast requires both operands to be pointer or neither", &I); + Assert1(SrcBitSize == DestBitSize, "Bitcast requies types of same width", &I); + + visitInstruction(I); +} + /// visitPHINode - Ensure that a PHI node is well formed. /// void Verifier::visitPHINode(PHINode &PN) { diff --git a/projects/Stacker/lib/compiler/StackerCompiler.cpp b/projects/Stacker/lib/compiler/StackerCompiler.cpp index 9b0cabb2fb..aaf7812ca1 100644 --- a/projects/Stacker/lib/compiler/StackerCompiler.cpp +++ b/projects/Stacker/lib/compiler/StackerCompiler.cpp @@ -367,7 +367,7 @@ StackerCompiler::incr_stack_index( BasicBlock* bb, Value* ival = 0 ) // Increment the loaded index value if ( ival == 0 ) ival = One; - CastInst* caster = new CastInst( ival, Type::LongTy ); + CastInst* caster = CastInst::createInferredCast( ival, Type::LongTy ); bb->getInstList().push_back( caster ); BinaryOperator* addop = BinaryOperator::create( Instruction::Add, loadop, caster); @@ -388,7 +388,7 @@ StackerCompiler::decr_stack_index( BasicBlock* bb, Value* ival = 0 ) // Decrement the loaded index value if ( ival == 0 ) ival = One; - CastInst* caster = new CastInst( ival, Type::LongTy ); + CastInst* caster = CastInst::createInferredCast( ival, Type::LongTy ); bb->getInstList().push_back( caster ); BinaryOperator* subop = BinaryOperator::create( Instruction::Sub, loadop, caster); @@ -422,7 +422,7 @@ StackerCompiler::get_stack_pointer( BasicBlock* bb, Value* index = 0 ) } else { - CastInst* caster = new CastInst( index, Type::LongTy ); + CastInst* caster = CastInst::createInferredCast( index, Type::LongTy ); bb->getInstList().push_back( caster ); BinaryOperator* subop = BinaryOperator::create( Instruction::Sub, loadop, caster ); @@ -448,7 +448,7 @@ StackerCompiler::push_value( BasicBlock* bb, Value* val ) get_stack_pointer( bb ) ); // Cast the value to a long .. hopefully it works - CastInst* cast_inst = new CastInst( val, Type::LongTy ); + CastInst* cast_inst = CastInst::createInferredCast( val, Type::LongTy ); bb->getInstList().push_back( cast_inst ); // Store the value @@ -522,7 +522,8 @@ StackerCompiler::pop_string( BasicBlock* bb ) bb->getInstList().push_back( loader ); // Cast the integer to a sbyte* - CastInst* caster = new CastInst( loader, PointerType::get(Type::SByteTy) ); + CastInst* caster = + CastInst::createInferredCast( loader, PointerType::get(Type::SByteTy) ); bb->getInstList().push_back( caster ); // Decrement stack index @@ -574,7 +575,8 @@ StackerCompiler::stack_top_string( BasicBlock* bb, Value* index = 0 ) bb->getInstList().push_back( loader ); // Cast the integer to a sbyte* - CastInst* caster = new CastInst( loader, PointerType::get(Type::SByteTy) ); + CastInst* caster = + CastInst::createInferredCast( loader, PointerType::get(Type::SByteTy) ); bb->getInstList().push_back( caster ); // Return the value @@ -1243,7 +1245,7 @@ StackerCompiler::handle_word( int tkn ) if (echo) bb->setName("SHL"); LoadInst* op1 = cast<LoadInst>(pop_integer(bb)); LoadInst* op2 = cast<LoadInst>(pop_integer(bb)); - CastInst* castop = new CastInst( op1, Type::UByteTy ); + CastInst* castop = CastInst::createInferredCast( op1, Type::UByteTy ); bb->getInstList().push_back( castop ); ShiftInst* shlop = new ShiftInst( Instruction::Shl, op2, castop ); bb->getInstList().push_back( shlop ); @@ -1255,7 +1257,7 @@ StackerCompiler::handle_word( int tkn ) if (echo) bb->setName("SHR"); LoadInst* op1 = cast<LoadInst>(pop_integer(bb)); LoadInst* op2 = cast<LoadInst>(pop_integer(bb)); - CastInst* castop = new CastInst( op1, Type::UByteTy ); + CastInst* castop = CastInst::createInferredCast( op1, Type::UByteTy ); bb->getInstList().push_back( castop ); ShiftInst* shrop = new ShiftInst( Instruction::AShr, op2, castop ); bb->getInstList().push_back( shrop ); @@ -1477,7 +1479,7 @@ StackerCompiler::handle_word( int tkn ) LoadInst* op1 = cast<LoadInst>( pop_integer(bb) ); // Make sure its a UIntTy - CastInst* caster = new CastInst( op1, Type::UIntTy ); + CastInst* caster = CastInst::createInferredCast( op1, Type::UIntTy ); bb->getInstList().push_back( caster ); // Allocate the bytes @@ -1505,7 +1507,7 @@ StackerCompiler::handle_word( int tkn ) if (echo) bb->setName("GET"); // Get the character index LoadInst* op1 = cast<LoadInst>( stack_top(bb) ); - CastInst* chr_idx = new CastInst( op1, Type::LongTy ); + CastInst* chr_idx = CastInst::createInferredCast( op1, Type::LongTy ); bb->getInstList().push_back( chr_idx ); // Get the String pointer @@ -1520,7 +1522,7 @@ StackerCompiler::handle_word( int tkn ) // Get the value and push it LoadInst* loader = new LoadInst( gep ); bb->getInstList().push_back( loader ); - CastInst* caster = new CastInst( loader, Type::IntTy ); + CastInst* caster = CastInst::createInferredCast( loader, Type::IntTy ); bb->getInstList().push_back( caster ); // Push the result back on stack @@ -1537,7 +1539,7 @@ StackerCompiler::handle_word( int tkn ) // Get the character index LoadInst* w2 = cast<LoadInst>( pop_integer(bb) ); - CastInst* chr_idx = new CastInst( w2, Type::LongTy ); + CastInst* chr_idx = CastInst::createInferredCast( w2, Type::LongTy ); bb->getInstList().push_back( chr_idx ); // Get the String pointer @@ -1550,7 +1552,7 @@ StackerCompiler::handle_word( int tkn ) bb->getInstList().push_back( gep ); // Cast the value and put it - CastInst* caster = new CastInst( w1, Type::SByteTy ); + CastInst* caster = CastInst::createInferredCast( w1, Type::SByteTy ); bb->getInstList().push_back( caster ); StoreInst* storer = new StoreInst( caster, gep ); bb->getInstList().push_back( storer ); @@ -1578,7 +1580,7 @@ StackerCompiler::handle_word( int tkn ) LoadInst* op1 = cast<LoadInst>(pop_integer(bb)); // Cast down to an integer - CastInst* caster = new CastInst( op1, Type::IntTy ); + CastInst* caster = CastInst::createInferredCast( op1, Type::IntTy ); bb->getInstList().push_back( caster ); // Call exit(3) @@ -1660,9 +1662,9 @@ StackerCompiler::handle_word( int tkn ) // Make room for the value result incr_stack_index(bb); GetElementPtrInst* gep_value = - cast<GetElementPtrInst>(get_stack_pointer(bb)); - CastInst* caster = - new CastInst( gep_value, PointerType::get( Type::SByteTy ) ); + cast<GetElementPtrInst>(get_stack_pointer(bb)); + CastInst* caster = + new BitCastInst(gep_value, PointerType::get(Type::SByteTy)); // Make room for the count result incr_stack_index(bb); diff --git a/test/Analysis/LoadVN/casts.ll b/test/Analysis/LoadVN/casts.ll new file mode 100644 index 0000000000..462338d0d8 --- /dev/null +++ b/test/Analysis/LoadVN/casts.ll @@ -0,0 +1,12 @@ +; Check to make sure that Value Numbering doesn't merge casts of different +; flavors. +; RUN: llvm-as < %s | opt -load-vn -gcse | llvm-dis | grep '[sz]ext' | wc -l | grep 2 + +declare void %external(int) + +int %test_casts(short %x) { + %a = sext short %x to int + %b = zext short %x to int + call void %external(int %a) + ret int %b +} diff --git a/test/Assembler/2003-11-12-ConstantExprCast.llx b/test/Assembler/2003-11-12-ConstantExprCast.llx index bceae9f388..8b3f05128b 100644 --- a/test/Assembler/2003-11-12-ConstantExprCast.llx +++ b/test/Assembler/2003-11-12-ConstantExprCast.llx @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llvm-dis | grep ' cast (' +; RUN: llvm-as < %s | llvm-dis | grep ' bitcast (' %.Base64_1 = external constant [4 x sbyte] diff --git a/test/CFrontend/cast-to-bool.c b/test/CFrontend/cast-to-bool.c new file mode 100644 index 0000000000..ddf21b0854 --- /dev/null +++ b/test/CFrontend/cast-to-bool.c @@ -0,0 +1,16 @@ +// RUN: %llvmgcc -S %s -o - | grep 'trunc.*to bool' +// RUN: %llvmgcc -S %s -o - | llvm-as | llc -march=x86 | grep and +int +main ( int argc, char** argv) +{ + int i; + int result = 1; + for (i = 2; i <= 3; i++) + { + if ((i & 1) == 0) + { + result = result + 17; + } + } + return result; +} diff --git a/test/CodeGen/CBackend/2003-06-23-PromotedExprs.llx b/test/CodeGen/CBackend/2003-06-23-PromotedExprs.llx index d3ad57fc11..286d65b345 100644 --- a/test/CodeGen/CBackend/2003-06-23-PromotedExprs.llx +++ b/test/CodeGen/CBackend/2003-06-23-PromotedExprs.llx @@ -5,7 +5,7 @@ bool %doTest(ubyte %x) { %dec.0 = add ubyte %x, 255 - %tmp.1001 = cast ubyte %dec.0 to bool + %tmp.1001 = trunc ubyte %dec.0 to bool ret bool %tmp.1001 } diff --git a/test/CodeGen/X86/trunc-to-bool.ll b/test/CodeGen/X86/trunc-to-bool.ll new file mode 100644 index 0000000000..693b94c773 --- /dev/null +++ b/test/CodeGen/X86/trunc-to-bool.ll @@ -0,0 +1,32 @@ +; An integer truncation to bool should be done with an and instruction to make +; sure only the LSBit survives. Test that this is the case both for a returned +; value and as the operand of a branch. +; RUN: llvm-as < %s | llc -march=x86 && +; RUN: llvm-as < %s | llc -march=x86 | grep '\(and\)\|\(test.*1\)' | wc -l | grep 3 +bool %test1(int %X) { + %Y = trunc int %X to bool + ret bool %Y +} + +bool %test2(int %val, int %mask) { +entry: + %mask = trunc int %mask to ubyte + %shifted = ashr int %val, ubyte %mask + %anded = and int %shifted, 1 + %trunced = trunc int %anded to bool + br bool %trunced, label %ret_true, label %ret_false +ret_true: + ret bool true +ret_false: + ret bool false +} + +int %test3(sbyte* %ptr) { + %val = load sbyte* %ptr + %tmp = trunc sbyte %val to bool ; %<bool> [#uses=1] + br bool %tmp, label %cond_true, label %cond_false +cond_true: + ret int 21 +cond_false: + ret int 42 +} diff --git a/test/Feature/casttest.ll b/test/Feature/casttest.ll index acd47e575b..e7d8756791 100644 --- a/test/Feature/casttest.ll +++ b/test/Feature/casttest.ll @@ -2,7 +2,21 @@ ; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll ; RUN: diff %t1.ll %t2.ll -implementation +void "NewCasts" (short %x) { + %a = zext short %x to int + %b = sext short %x to uint + %c = trunc short %x to ubyte + %d = uitofp short %x to float + %e = sitofp short %x to double + %f = fptoui float %d to short + %g = fptosi double %e to short + %i = fpext float %d to double + %j = fptrunc double %i to float + %k = bitcast int %a to float + %l = inttoptr short %x to int* + %m = ptrtoint int* %l to long + ret void +} short "FunFunc"(long %x, sbyte %z) begin diff --git a/test/Transforms/IPConstantProp/return-constant.ll b/test/Transforms/IPConstantProp/return-constant.ll index a3e2832c5e..f779d76af1 100644 --- a/test/Transforms/IPConstantProp/return-constant.ll +++ b/test/Transforms/IPConstantProp/return-constant.ll @@ -11,6 +11,6 @@ F: bool %caller(bool %C) { %X = call int %foo(bool %C) - %Y = cast int %X to bool + %Y = trunc int %X to bool ret bool %Y } diff --git a/test/Transforms/Inline/casts.ll b/test/Transforms/Inline/casts.ll new file mode 100644 index 0000000000..8b597adca0 --- /dev/null +++ b/test/Transforms/Inline/casts.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | opt -inline | llvm-dis | grep 'ret int 1' +; ModuleID = 'short.opt.bc' + +implementation ; Functions: + +int %testBool(bool %X) { + %tmp = zext bool %X to int ; <int> [#uses=1] + ret int %tmp +} + +int %testByte(sbyte %X) { + %tmp = setne sbyte %X, 0 ; <bool> [#uses=1] + %tmp.i = zext bool %tmp to int ; <int> [#uses=1] + ret int %tmp.i +} + +int %main() { + %rslt = call int %testByte( sbyte 123) + ret int %rslt +} diff --git a/test/Transforms/InstCombine/2003-11-03-VarargsCallBug.ll b/test/Transforms/InstCombine/2003-11-03-VarargsCallBug.ll index 051add8c0b..7e045d8541 100644 --- a/test/Transforms/InstCombine/2003-11-03-VarargsCallBug.ll +++ b/test/Transforms/InstCombine/2003-11-03-VarargsCallBug.ll @@ -1,5 +1,5 @@ ; The cast in this testcase is not eliminatable on a 32-bit target! -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep cast +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep inttoptr target endian = little target pointersize = 32 diff --git a/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst-2.ll b/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst-2.ll index c10e62db8e..f7925e138d 100644 --- a/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst-2.ll +++ b/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst-2.ll @@ -1,5 +1,5 @@ ; The optimizer should be able to remove cast operation here. -; RUN: llvm-as %s -o - | opt -instcombine | llvm-dis | not grep 'cast.*int' +; RUN: llvm-as %s -o - | opt -instcombine | llvm-dis | not grep 'sext.*int' bool %eq_signed_to_small_unsigned(sbyte %SB) { %Y = cast sbyte %SB to uint ; <uint> [#uses=1] diff --git a/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll b/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll index e35c36694f..f23f5fb229 100644 --- a/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll +++ b/test/Transforms/InstCombine/2006-10-19-SignedToUnsignedCastAndConst.ll @@ -1,8 +1,9 @@ ; This test case is reduced from llvmAsmParser.cpp ; The optimizer should not remove the cast here. -; RUN: llvm-as %s -o - | opt -instcombine | llvm-dis | grep 'cast.*int' +; RUN: llvm-as %s -o - | opt -instcombine | llvm-dis | grep 'sext.*int' + bool %test(short %X) { -%A = cast short %X to uint -%B = setgt uint %A, 1330 -ret bool %B + %A = cast short %X to uint + %B = setgt uint %A, 1330 + ret bool %B } diff --git a/test/Transforms/InstCombine/binop-cast.ll b/test/Transforms/InstCombine/binop-cast.ll new file mode 100644 index 0000000000..13404df941 --- /dev/null +++ b/test/Transforms/InstCombine/binop-cast.ll @@ -0,0 +1,7 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | notcast + +uint %testAdd(int %X, int %Y) { + %tmp = add int %X, %Y + %tmp.l = sext int %tmp to uint + ret uint %tmp.l +} diff --git a/test/Transforms/InstCombine/call-cast-target.ll b/test/Transforms/InstCombine/call-cast-target.ll index a197742a66..77097caf29 100644 --- a/test/Transforms/InstCombine/call-cast-target.ll +++ b/test/Transforms/InstCombine/call-cast-target.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep call | not grep cast +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep call | not grep bitcast target endian = little target pointersize = 32 diff --git a/test/Transforms/InstCombine/cast-malloc.ll b/test/Transforms/InstCombine/cast-malloc.ll new file mode 100644 index 0000000000..25eb4367c6 --- /dev/null +++ b/test/Transforms/InstCombine/cast-malloc.ll @@ -0,0 +1,8 @@ +; test that casted mallocs get converted to malloc of the right type +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep bitcast + +int* %test(uint %size) { + %X = malloc long, uint %size + %ret = bitcast long* %X to int* + ret int* %ret +} diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index ba0b30452c..4accb47af2 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -1,6 +1,6 @@ ; Tests to make sure elimination of casts is working correctly ; RUN: llvm-as < %s | opt -instcombine -disable-output && -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep '%c' | not grep cast +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep '%c' | notcast %inbuf = external global [32832 x ubyte] @@ -104,7 +104,6 @@ bool %test16(int* %P) { ret bool %c } - short %test17(bool %tmp3) { %c = cast bool %tmp3 to int %t86 = cast int %c to short @@ -207,3 +206,8 @@ void %test32(double** %tmp) { ret void } +uint %test33(uint %c1) { + %x = bitcast uint %c1 to float + %y = bitcast float %x to uint + ret uint %y +} diff --git a/test/Transforms/InstCombine/cast_ptr.ll b/test/Transforms/InstCombine/cast_ptr.ll index be0a8970dc..7b572560e4 100644 --- a/test/Transforms/InstCombine/cast_ptr.ll +++ b/test/Transforms/InstCombine/cast_ptr.ll @@ -1,6 +1,6 @@ ; Tests to make sure elimination of casts is working correctly ; RUN: llvm-as < %s | opt -instcombine -disable-output && -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep cast +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep '\([sz]ext\)\|\(trunc\)' target pointersize = 32 diff --git a/test/Transforms/InstCombine/fpcast.ll b/test/Transforms/InstCombine/fpcast.ll new file mode 100644 index 0000000000..31cd47f619 --- /dev/null +++ b/test/Transforms/InstCombine/fpcast.ll @@ -0,0 +1,14 @@ +; Test some floating point casting cases +; RUN: llvm-as %s -o - | opt -instcombine | llvm-dis | notcast +; RUN: llvm-as %s -o - | opt -instcombine | llvm-dis | \ +; RUN: grep 'ret [us]byte \(-1\)\|\(255\)' + +sbyte %test() { + %x = fptoui float 255.0 to sbyte + ret sbyte %x +} + +ubyte %test() { + %x = fptosi float -1.0 to ubyte + ret ubyte %x +} diff --git a/test/Transforms/InstCombine/getelementptr_cast.ll b/test/Transforms/InstCombine/getelementptr_cast.ll index ece73f7710..b600874e12 100644 --- a/test/Transforms/InstCombine/getelementptr_cast.ll +++ b/test/Transforms/InstCombine/getelementptr_cast.ll @@ -1,9 +1,9 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'getelementptr.*cast' +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | notcast '' 'getelementptr.*' %G = external global [3 x sbyte] implementation ubyte *%foo(uint %Idx) { -%tmp = getelementptr ubyte* cast ([3 x sbyte]* %G to ubyte*), uint %Idx -ret ubyte* %tmp + %tmp = getelementptr ubyte* cast ([3 x sbyte]* %G to ubyte*), uint %Idx + ret ubyte* %tmp } diff --git a/test/Transforms/InstCombine/getelementptr_index.ll b/test/Transforms/InstCombine/getelementptr_index.ll index ca7d6e0465..8346fa5191 100644 --- a/test/Transforms/InstCombine/getelementptr_index.ll +++ b/test/Transforms/InstCombine/getelementptr_index.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep cast +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep trunc target endian = little target pointersize = 32 diff --git a/test/Transforms/InstCombine/narrow.ll b/test/Transforms/InstCombine/narrow.ll index b8be8c3055..75a78a3f8b 100644 --- a/test/Transforms/InstCombine/narrow.ll +++ b/test/Transforms/InstCombine/narrow.ll @@ -8,10 +8,10 @@ ; bool %test1(int %A, int %B) { %C1 = setlt int %A, %B - %ELIM1 = cast bool %C1 to uint + %ELIM1 = zext bool %C1 to uint %C2 = setgt int %A, %B - %ELIM2 = cast bool %C2 to uint + %ELIM2 = zext bool %C2 to uint %C3 = and uint %ELIM1, %ELIM2 - %ELIM3 = cast uint %C3 to bool + %ELIM3 = trunc uint %C3 to bool ret bool %ELIM3 } diff --git a/test/Transforms/InstCombine/setcc-cast-cast.ll b/test/Transforms/InstCombine/setcc-cast-cast.ll new file mode 100644 index 0000000000..e311c523fb --- /dev/null +++ b/test/Transforms/InstCombine/setcc-cast-cast.ll @@ -0,0 +1,42 @@ +; This test case was reduced from MultiSource/Applications/hbd. It makes sure +; that folding doesn't happen in case a zext is applied where a sext should have +; been when a setcc is used with two casts. +; RUN: llvm-as < %s | llc -instcombine | llvm-dis | not grep 'br bool false' +int %bug(ubyte %inbuff) { +entry: + %tmp = bitcast ubyte %inbuff to sbyte ; <sbyte> [#uses=1] + %tmp = sext sbyte %tmp to int ; <int> [#uses=3] + %tmp = seteq int %tmp, 1 ; <bool> [#uses=1] + br bool %tmp, label %cond_true, label %cond_next + +cond_true: ; preds = %entry + br label %bb + +cond_next: ; preds = %entry + %tmp3 = seteq int %tmp, -1 ; <bool> [#uses=1] + br bool %tmp3, label %cond_true4, label %cond_next5 + +cond_true4: ; preds = %cond_next + br label %bb + +cond_next5: ; preds = %cond_next + %tmp7 = setgt int %tmp, 1 ; <bool> [#uses=1] + br bool %tmp7, label %cond_true8, label %cond_false + +cond_true8: ; preds = %cond_next5 + br label %cond_next9 + +cond_false: ; preds = %cond_next5 + br label %cond_next9 + +cond_next9: ; preds = %cond_false, %cond_true8 + %iftmp.1.0 = phi int [ 42, %cond_true8 ], [ 23, %cond_false ] ; <int> [#uses=1] + br label %return + +bb: ; preds = %cond_true4, %cond_true + br label %return + +return: ; preds = %bb, %cond_next9 + %retval.0 = phi int [ 17, %bb ], [ %iftmp.1.0, %cond_next9 ] ; <int> [#uses=1] + ret int %retval.0 +} diff --git a/test/Transforms/InstCombine/zext.ll b/test/Transforms/InstCombine/zext.ll new file mode 100644 index 0000000000..27442aab61 --- /dev/null +++ b/test/Transforms/InstCombine/zext.ll @@ -0,0 +1,9 @@ +; Tests to make sure elimination of casts is working correctly +; RUN: llvm-as < %s | opt -instcombine -disable-output && +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | notcast '' '%c1.*' + +long %test_sext_zext(short %A) { + %c1 = zext short %A to uint + %c2 = sext uint %c1 to long + ret long %c2 +} diff --git a/test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll b/test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll index 61c39723c1..5f6250ef33 100644 --- a/test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll +++ b/test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll @@ -1,8 +1,8 @@ -; This example should be raised to return a Hash directly without casting. To -; successful, all cast instructions should be eliminated from this testcase. +; This example should be raised to return a Hash directly without casting. +; LevelRaise should eliminate all cast instructions from this testcase. ; ; XFAIL: * -; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep cast +; RUN: llvm-as < %s | opt -raise | llvm-dis | notcast %Hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } * %hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } diff --git a/test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll b/test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll index be25022e49..4a778ea0e5 100644 --- a/test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll +++ b/test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll @@ -3,7 +3,7 @@ ; prevented reg115 from being able to change. ; ; XFAIL: * -; RUN: llvm-as < %s | opt -raise | llvm-dis | grep '= cast' | not grep \* +; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep bitcast %Hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } * %HashEntry = type { uint, sbyte *, \2 } * diff --git a/test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll b/test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll index b3e42cc9dc..6379ab5848 100644 --- a/test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll +++ b/test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll @@ -1,5 +1,5 @@ ; XFAIL: * -; RUN: llvm-as < %s | opt -raise | llvm-dis | grep '= cast' | not grep \* +; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep bitcast %Hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } * %HashEntry = type { uint, sbyte *, \2 } * diff --git a/test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll b/test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll index c1a4e056a9..1fa2fd8253 100644 --- a/test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll +++ b/test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll @@ -6,7 +6,7 @@ ; return (int*)malloc(i+j); ; } -; RUN: llvm-as < %s | opt -raise | llvm-dis | grep ' cast ' | not grep '*' +; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep bitcast implementation diff --git a/test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll b/test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll index 615217e09c..64000918de 100644 --- a/test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll +++ b/test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll @@ -1,6 +1,6 @@ ; This testcase is not level raised properly... ; XFAIL: * -; RUN: llvm-as < %s | opt -raise | llvm-dis | grep ' cast ' | not grep '*' +; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep bitcast %List = type { int, %List* } diff --git a/test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll b/test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll index 1e2ca0e0e9..102b57431f 100644 --- a/test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll +++ b/test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll @@ -1,7 +1,7 @@ ; This testcase should have the cast propogated through the load ; just like a store does... ; -; RUN: llvm-as < %s | opt -raise | llvm-dis | grep ' cast ' | not grep '*' +; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep 'bitcast uint \*' int "test"(uint * %Ptr) { %P2 = cast uint *%Ptr to int * diff --git a/test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll b/test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll index c092e6b181..59a4248d5a 100644 --- a/test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll +++ b/test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll @@ -1,5 +1,5 @@ ; XFAIL: * -; RUN: llvm-as < %s | opt -raise | llvm-dis | grep '= cast' | not grep \* +; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep bitcast %FILE = type { int, ubyte*, ubyte*, ubyte, ubyte, uint, uint, uint } diff --git a/test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll b/test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll index c3406bab72..a5ed52ccb5 100644 --- a/test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll +++ b/test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll @@ -5,7 +5,7 @@ ; This could be fixed by making all stores add themselves to a list, and check ; their arguments are consistent AFTER all other values are propogated. ; XFAIL: * -; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep '= cast' +; RUN: llvm-as < %s | opt -raise | llvm-dis | notcast %Tree = type %struct.tree* %struct.tree = type { int, double, double, %Tree, %Tree, %Tree, %Tree } diff --git a/test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll b/test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll index 422b977e24..91301f0510 100644 --- a/test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll +++ b/test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll @@ -1,6 +1,6 @@ ; Looks like we don't raise alloca's like we do mallocs ; XFAIL: * -; RUN: llvm-as < %s | opt -raise | llvm-dis | grep '= cast' | not grep \* +; RUN: llvm-as < %s | opt -raise | llvm-dis | not grep bitcast implementation ; Functions: diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index 4be2232a36..43e68404cb 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -214,7 +214,7 @@ static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2){ Constant *FP = CS->getOperand(1); if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) - if (CE->getOpcode() == Instruction::Cast) + if (CE->isCast()) FP = CE->getOperand(0); if (Function *F = dyn_cast<Function>(FP)) { if (!F->isExternal()) diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index c5eaa0769a..f674324180 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -734,9 +734,9 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, CallInst *Resolver = new CallInst(resolverFunc, ResolverArgs, "resolver", LookupBB); // cast the result from the resolver to correctly-typed function - CastInst *CastedResolver = - new CastInst(Resolver, PointerType::get(F->getFunctionType()), - "resolverCast", LookupBB); + CastInst *CastedResolver = new BitCastInst(Resolver, + PointerType::get(F->getFunctionType()), "resolverCast", LookupBB); + // Save the value in our cache. new StoreInst(CastedResolver, Cache, LookupBB); new BranchInst(DoCallBB, LookupBB); diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp index 79c3d9d1c1..b1f717d0bf 100644 --- a/tools/llvm2cpp/CppWriter.cpp +++ b/tools/llvm2cpp/CppWriter.cpp @@ -757,7 +757,7 @@ void CppWriter::printConstant(const Constant *CV) { << " = ConstantExpr::getGetElementPtr(" << getCppName(CE->getOperand(0)) << ", " << constName << "_indices);"; - } else if (CE->getOpcode() == Instruction::Cast) { + } else if (CE->isCast()) { printConstant(CE->getOperand(0)); Out << "Constant* " << constName << " = ConstantExpr::getCast("; Out << getCppName(CE->getOperand(0)) << ", " << getCppName(CE->getType()) @@ -1174,10 +1174,36 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname) { } break; } - case Instruction::Cast: { + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: { const CastInst* cst = cast<CastInst>(I); - Out << "CastInst* " << iName << " = new CastInst(" - << opNames[0] << ", " + Out << "CastInst* " << iName << " = new "; + switch (I->getOpcode()) { + case Instruction::Trunc: Out << "TruncInst"; + case Instruction::ZExt: Out << "ZExtInst"; + case Instruction::SExt: Out << "SExtInst"; + case Instruction::FPTrunc: Out << "FPTruncInst"; + case Instruction::FPExt: Out << "FPExtInst"; + case Instruction::FPToUI: Out << "FPToUIInst"; + case Instruction::FPToSI: Out << "FPToSIInst"; + case Instruction::UIToFP: Out << "UIToFPInst"; + case Instruction::SIToFP: Out << "SIToFPInst"; + case Instruction::PtrToInt: Out << "PtrToInst"; + case Instruction::IntToPtr: Out << "IntToPtrInst"; + case Instruction::BitCast: Out << "BitCastInst"; + default: assert(!"Unreachable"); break; + } + Out << "(" << opNames[0] << ", " << getCppName(cst->getType()) << ", \""; printEscapedString(cst->getName()); Out << "\", " << bbname << ");"; |