forked from OSchip/llvm-project
parent
7a697bc8dc
commit
26ee2b8477
|
@ -57,7 +57,7 @@ namespace llvm {
|
||||||
|
|
||||||
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
|
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ namespace llvm {
|
||||||
|
|
||||||
/// SimplifySRemInst - Given operands for an SRem, see if we can
|
/// SimplifySRemInst - Given operands for an SRem, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ namespace llvm {
|
||||||
/// SimplifyShlInst - Given operands for a Shl, see if we can
|
/// SimplifyShlInst - Given operands for a Shl, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
|
@ -127,14 +127,14 @@ namespace llvm {
|
||||||
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
|
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ namespace llvm {
|
||||||
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
|
||||||
/// fold the result. If not, this returns null.
|
/// fold the result. If not, this returns null.
|
||||||
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||||
const DataLayout *TD = 0,
|
const DataLayout *TD = 0,
|
||||||
const TargetLibraryInfo *TLI = 0,
|
const TargetLibraryInfo *TLI = 0,
|
||||||
const DominatorTree *DT = 0);
|
const DominatorTree *DT = 0);
|
||||||
|
|
||||||
|
|
|
@ -31,16 +31,16 @@ namespace bitc {
|
||||||
PARAMATTR_BLOCK_ID,
|
PARAMATTR_BLOCK_ID,
|
||||||
|
|
||||||
UNUSED_ID1,
|
UNUSED_ID1,
|
||||||
|
|
||||||
CONSTANTS_BLOCK_ID,
|
CONSTANTS_BLOCK_ID,
|
||||||
FUNCTION_BLOCK_ID,
|
FUNCTION_BLOCK_ID,
|
||||||
|
|
||||||
UNUSED_ID2,
|
UNUSED_ID2,
|
||||||
|
|
||||||
VALUE_SYMTAB_BLOCK_ID,
|
VALUE_SYMTAB_BLOCK_ID,
|
||||||
METADATA_BLOCK_ID,
|
METADATA_BLOCK_ID,
|
||||||
METADATA_ATTACHMENT_ID,
|
METADATA_ATTACHMENT_ID,
|
||||||
|
|
||||||
TYPE_BLOCK_ID_NEW,
|
TYPE_BLOCK_ID_NEW,
|
||||||
|
|
||||||
USELIST_BLOCK_ID
|
USELIST_BLOCK_ID
|
||||||
|
@ -93,9 +93,9 @@ namespace bitc {
|
||||||
|
|
||||||
TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty,
|
TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty,
|
||||||
// paramty x N]
|
// paramty x N]
|
||||||
|
|
||||||
TYPE_CODE_HALF = 10, // HALF
|
TYPE_CODE_HALF = 10, // HALF
|
||||||
|
|
||||||
TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty]
|
TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty]
|
||||||
TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty]
|
TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty]
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ namespace bitc {
|
||||||
TYPE_CODE_METADATA = 16, // METADATA
|
TYPE_CODE_METADATA = 16, // METADATA
|
||||||
|
|
||||||
TYPE_CODE_X86_MMX = 17, // X86 MMX
|
TYPE_CODE_X86_MMX = 17, // X86 MMX
|
||||||
|
|
||||||
TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N]
|
TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N]
|
||||||
TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
|
TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
|
||||||
TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N]
|
TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N]
|
||||||
|
@ -234,7 +234,7 @@ namespace bitc {
|
||||||
OBO_NO_SIGNED_WRAP = 1
|
OBO_NO_SIGNED_WRAP = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/// PossiblyExactOperatorOptionalFlags - Flags for serializing
|
/// PossiblyExactOperatorOptionalFlags - Flags for serializing
|
||||||
/// PossiblyExactOperator's SubclassOptionalData contents.
|
/// PossiblyExactOperator's SubclassOptionalData contents.
|
||||||
enum PossiblyExactOperatorOptionalFlags {
|
enum PossiblyExactOperatorOptionalFlags {
|
||||||
PEO_EXACT = 0
|
PEO_EXACT = 0
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Instruction : public User, public ilist_node<Instruction> {
|
||||||
|
|
||||||
BasicBlock *Parent;
|
BasicBlock *Parent;
|
||||||
DebugLoc DbgLoc; // 'dbg' Metadata cache.
|
DebugLoc DbgLoc; // 'dbg' Metadata cache.
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/// HasMetadataBit - This is a bit stored in the SubClassData field which
|
/// HasMetadataBit - This is a bit stored in the SubClassData field which
|
||||||
/// indicates whether this instruction has metadata attached to it or not.
|
/// indicates whether this instruction has metadata attached to it or not.
|
||||||
|
@ -42,12 +42,12 @@ class Instruction : public User, public ilist_node<Instruction> {
|
||||||
public:
|
public:
|
||||||
// Out of line virtual method, so the vtable, etc has a home.
|
// Out of line virtual method, so the vtable, etc has a home.
|
||||||
~Instruction();
|
~Instruction();
|
||||||
|
|
||||||
/// use_back - Specialize the methods defined in Value, as we know that an
|
/// use_back - Specialize the methods defined in Value, as we know that an
|
||||||
/// instruction can only be used by other instructions.
|
/// instruction can only be used by other instructions.
|
||||||
Instruction *use_back() { return cast<Instruction>(*use_begin());}
|
Instruction *use_back() { return cast<Instruction>(*use_begin());}
|
||||||
const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
|
const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
|
||||||
|
|
||||||
inline const BasicBlock *getParent() const { return Parent; }
|
inline const BasicBlock *getParent() const { return Parent; }
|
||||||
inline BasicBlock *getParent() { return Parent; }
|
inline BasicBlock *getParent() { return Parent; }
|
||||||
|
|
||||||
|
@ -77,16 +77,16 @@ public:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Subclass classification.
|
// Subclass classification.
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// getOpcode() returns a member of one of the enums like Instruction::Add.
|
/// getOpcode() returns a member of one of the enums like Instruction::Add.
|
||||||
unsigned getOpcode() const { return getValueID() - InstructionVal; }
|
unsigned getOpcode() const { return getValueID() - InstructionVal; }
|
||||||
|
|
||||||
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
|
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
|
||||||
bool isTerminator() const { return isTerminator(getOpcode()); }
|
bool isTerminator() const { return isTerminator(getOpcode()); }
|
||||||
bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
|
bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
|
||||||
bool isShift() { return isShift(getOpcode()); }
|
bool isShift() { return isShift(getOpcode()); }
|
||||||
bool isCast() const { return isCast(getOpcode()); }
|
bool isCast() const { return isCast(getOpcode()); }
|
||||||
|
|
||||||
static const char* getOpcodeName(unsigned OpCode);
|
static const char* getOpcodeName(unsigned OpCode);
|
||||||
|
|
||||||
static inline bool isTerminator(unsigned OpCode) {
|
static inline bool isTerminator(unsigned OpCode) {
|
||||||
|
@ -121,33 +121,33 @@ public:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Metadata manipulation.
|
// Metadata manipulation.
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// hasMetadata() - Return true if this instruction has any metadata attached
|
/// hasMetadata() - Return true if this instruction has any metadata attached
|
||||||
/// to it.
|
/// to it.
|
||||||
bool hasMetadata() const {
|
bool hasMetadata() const {
|
||||||
return !DbgLoc.isUnknown() || hasMetadataHashEntry();
|
return !DbgLoc.isUnknown() || hasMetadataHashEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// hasMetadataOtherThanDebugLoc - Return true if this instruction has
|
/// hasMetadataOtherThanDebugLoc - Return true if this instruction has
|
||||||
/// metadata attached to it other than a debug location.
|
/// metadata attached to it other than a debug location.
|
||||||
bool hasMetadataOtherThanDebugLoc() const {
|
bool hasMetadataOtherThanDebugLoc() const {
|
||||||
return hasMetadataHashEntry();
|
return hasMetadataHashEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getMetadata - Get the metadata of given kind attached to this Instruction.
|
/// getMetadata - Get the metadata of given kind attached to this Instruction.
|
||||||
/// If the metadata is not found then return null.
|
/// If the metadata is not found then return null.
|
||||||
MDNode *getMetadata(unsigned KindID) const {
|
MDNode *getMetadata(unsigned KindID) const {
|
||||||
if (!hasMetadata()) return 0;
|
if (!hasMetadata()) return 0;
|
||||||
return getMetadataImpl(KindID);
|
return getMetadataImpl(KindID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getMetadata - Get the metadata of given kind attached to this Instruction.
|
/// getMetadata - Get the metadata of given kind attached to this Instruction.
|
||||||
/// If the metadata is not found then return null.
|
/// If the metadata is not found then return null.
|
||||||
MDNode *getMetadata(StringRef Kind) const {
|
MDNode *getMetadata(StringRef Kind) const {
|
||||||
if (!hasMetadata()) return 0;
|
if (!hasMetadata()) return 0;
|
||||||
return getMetadataImpl(Kind);
|
return getMetadataImpl(Kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getAllMetadata - Get all metadata attached to this Instruction. The first
|
/// getAllMetadata - Get all metadata attached to this Instruction. The first
|
||||||
/// element of each pair returned is the KindID, the second element is the
|
/// element of each pair returned is the KindID, the second element is the
|
||||||
/// metadata value. This list is returned sorted by the KindID.
|
/// metadata value. This list is returned sorted by the KindID.
|
||||||
|
@ -155,7 +155,7 @@ public:
|
||||||
if (hasMetadata())
|
if (hasMetadata())
|
||||||
getAllMetadataImpl(MDs);
|
getAllMetadataImpl(MDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getAllMetadataOtherThanDebugLoc - This does the same thing as
|
/// getAllMetadataOtherThanDebugLoc - This does the same thing as
|
||||||
/// getAllMetadata, except that it filters out the debug location.
|
/// getAllMetadata, except that it filters out the debug location.
|
||||||
void getAllMetadataOtherThanDebugLoc(SmallVectorImpl<std::pair<unsigned,
|
void getAllMetadataOtherThanDebugLoc(SmallVectorImpl<std::pair<unsigned,
|
||||||
|
@ -163,7 +163,7 @@ public:
|
||||||
if (hasMetadataOtherThanDebugLoc())
|
if (hasMetadataOtherThanDebugLoc())
|
||||||
getAllMetadataOtherThanDebugLocImpl(MDs);
|
getAllMetadataOtherThanDebugLocImpl(MDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setMetadata - Set the metadata of the specified kind to the specified
|
/// setMetadata - Set the metadata of the specified kind to the specified
|
||||||
/// node. This updates/replaces metadata if already present, or removes it if
|
/// node. This updates/replaces metadata if already present, or removes it if
|
||||||
/// Node is null.
|
/// Node is null.
|
||||||
|
@ -172,17 +172,17 @@ public:
|
||||||
|
|
||||||
/// setDebugLoc - Set the debug location information for this instruction.
|
/// setDebugLoc - Set the debug location information for this instruction.
|
||||||
void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
|
void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
|
||||||
|
|
||||||
/// getDebugLoc - Return the debug location for this node as a DebugLoc.
|
/// getDebugLoc - Return the debug location for this node as a DebugLoc.
|
||||||
const DebugLoc &getDebugLoc() const { return DbgLoc; }
|
const DebugLoc &getDebugLoc() const { return DbgLoc; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// hasMetadataHashEntry - Return true if we have an entry in the on-the-side
|
/// hasMetadataHashEntry - Return true if we have an entry in the on-the-side
|
||||||
/// metadata hash.
|
/// metadata hash.
|
||||||
bool hasMetadataHashEntry() const {
|
bool hasMetadataHashEntry() const {
|
||||||
return (getSubclassDataFromValue() & HasMetadataBit) != 0;
|
return (getSubclassDataFromValue() & HasMetadataBit) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are all implemented in Metadata.cpp.
|
// These are all implemented in Metadata.cpp.
|
||||||
MDNode *getMetadataImpl(unsigned KindID) const;
|
MDNode *getMetadataImpl(unsigned KindID) const;
|
||||||
MDNode *getMetadataImpl(StringRef Kind) const;
|
MDNode *getMetadataImpl(StringRef Kind) const;
|
||||||
|
@ -194,8 +194,8 @@ public:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Predicates and helper methods.
|
// Predicates and helper methods.
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
|
||||||
/// isAssociative - Return true if the instruction is associative:
|
/// isAssociative - Return true if the instruction is associative:
|
||||||
///
|
///
|
||||||
/// Associative operators satisfy: x op (y op z) === (x op y) op z
|
/// Associative operators satisfy: x op (y op z) === (x op y) op z
|
||||||
|
@ -271,12 +271,12 @@ public:
|
||||||
/// * The instruction has no name
|
/// * The instruction has no name
|
||||||
///
|
///
|
||||||
Instruction *clone() const;
|
Instruction *clone() const;
|
||||||
|
|
||||||
/// isIdenticalTo - Return true if the specified instruction is exactly
|
/// isIdenticalTo - Return true if the specified instruction is exactly
|
||||||
/// identical to the current one. This means that all operands match and any
|
/// identical to the current one. This means that all operands match and any
|
||||||
/// extra information (e.g. load is volatile) agree.
|
/// extra information (e.g. load is volatile) agree.
|
||||||
bool isIdenticalTo(const Instruction *I) const;
|
bool isIdenticalTo(const Instruction *I) const;
|
||||||
|
|
||||||
/// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it
|
/// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it
|
||||||
/// ignores the SubclassOptionalData flags, which specify conditions
|
/// ignores the SubclassOptionalData flags, which specify conditions
|
||||||
/// under which the instruction's result is undefined.
|
/// under which the instruction's result is undefined.
|
||||||
|
@ -291,7 +291,7 @@ public:
|
||||||
/// as equivalent.
|
/// as equivalent.
|
||||||
CompareUsingScalarTypes = 1<<1
|
CompareUsingScalarTypes = 1<<1
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This function determines if the specified instruction executes the same
|
/// This function determines if the specified instruction executes the same
|
||||||
/// operation as the current one. This means that the opcodes, type, operand
|
/// operation as the current one. This means that the opcodes, type, operand
|
||||||
/// types and any other factors affecting the operation must be the same. This
|
/// types and any other factors affecting the operation must be the same. This
|
||||||
|
@ -301,14 +301,14 @@ public:
|
||||||
/// the current one.
|
/// the current one.
|
||||||
/// @brief Determine if one instruction is the same operation as another.
|
/// @brief Determine if one instruction is the same operation as another.
|
||||||
bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const;
|
bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const;
|
||||||
|
|
||||||
/// isUsedOutsideOfBlock - Return true if there are any uses of this
|
/// isUsedOutsideOfBlock - Return true if there are any uses of this
|
||||||
/// instruction in blocks other than the specified block. Note that PHI nodes
|
/// instruction in blocks other than the specified block. Note that PHI nodes
|
||||||
/// are considered to evaluate their operands in the corresponding predecessor
|
/// are considered to evaluate their operands in the corresponding predecessor
|
||||||
/// block.
|
/// block.
|
||||||
bool isUsedOutsideOfBlock(const BasicBlock *BB) const;
|
bool isUsedOutsideOfBlock(const BasicBlock *BB) const;
|
||||||
|
|
||||||
|
|
||||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
static inline bool classof(const Value *V) {
|
static inline bool classof(const Value *V) {
|
||||||
return V->getValueID() >= Value::InstructionVal;
|
return V->getValueID() >= Value::InstructionVal;
|
||||||
|
@ -360,34 +360,34 @@ private:
|
||||||
unsigned short getSubclassDataFromValue() const {
|
unsigned short getSubclassDataFromValue() const {
|
||||||
return Value::getSubclassDataFromValue();
|
return Value::getSubclassDataFromValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setHasMetadataHashEntry(bool V) {
|
void setHasMetadataHashEntry(bool V) {
|
||||||
setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
|
setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
|
||||||
(V ? HasMetadataBit : 0));
|
(V ? HasMetadataBit : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class SymbolTableListTraits<Instruction, BasicBlock>;
|
friend class SymbolTableListTraits<Instruction, BasicBlock>;
|
||||||
void setParent(BasicBlock *P);
|
void setParent(BasicBlock *P);
|
||||||
protected:
|
protected:
|
||||||
// Instruction subclasses can stick up to 15 bits of stuff into the
|
// Instruction subclasses can stick up to 15 bits of stuff into the
|
||||||
// SubclassData field of instruction with these members.
|
// SubclassData field of instruction with these members.
|
||||||
|
|
||||||
// Verify that only the low 15 bits are used.
|
// Verify that only the low 15 bits are used.
|
||||||
void setInstructionSubclassData(unsigned short D) {
|
void setInstructionSubclassData(unsigned short D) {
|
||||||
assert((D & HasMetadataBit) == 0 && "Out of range value put into field");
|
assert((D & HasMetadataBit) == 0 && "Out of range value put into field");
|
||||||
setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D);
|
setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getSubclassDataFromInstruction() const {
|
unsigned getSubclassDataFromInstruction() const {
|
||||||
return getSubclassDataFromValue() & ~HasMetadataBit;
|
return getSubclassDataFromValue() & ~HasMetadataBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
|
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
|
||||||
Instruction *InsertBefore = 0);
|
Instruction *InsertBefore = 0);
|
||||||
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
|
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
|
||||||
BasicBlock *InsertAtEnd);
|
BasicBlock *InsertAtEnd);
|
||||||
virtual Instruction *clone_impl() const = 0;
|
virtual Instruction *clone_impl() const = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Instruction* is only 4-byte aligned.
|
// Instruction* is only 4-byte aligned.
|
||||||
|
@ -401,7 +401,7 @@ public:
|
||||||
}
|
}
|
||||||
enum { NumLowBitsAvailable = 2 };
|
enum { NumLowBitsAvailable = 2 };
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -131,21 +131,21 @@ public:
|
||||||
enum {
|
enum {
|
||||||
IsExact = (1 << 0)
|
IsExact = (1 << 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BinaryOperator;
|
friend class BinaryOperator;
|
||||||
friend class ConstantExpr;
|
friend class ConstantExpr;
|
||||||
void setIsExact(bool B) {
|
void setIsExact(bool B) {
|
||||||
SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
|
SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// isExact - Test whether this division is known to be exact, with
|
/// isExact - Test whether this division is known to be exact, with
|
||||||
/// zero remainder.
|
/// zero remainder.
|
||||||
bool isExact() const {
|
bool isExact() const {
|
||||||
return SubclassOptionalData & IsExact;
|
return SubclassOptionalData & IsExact;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isPossiblyExactOpcode(unsigned OpC) {
|
static bool isPossiblyExactOpcode(unsigned OpC) {
|
||||||
return OpC == Instruction::SDiv ||
|
return OpC == Instruction::SDiv ||
|
||||||
OpC == Instruction::UDiv ||
|
OpC == Instruction::UDiv ||
|
||||||
|
@ -182,7 +182,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// ConcreteOperator - A helper template for defining operators for individual
|
/// ConcreteOperator - A helper template for defining operators for individual
|
||||||
/// opcodes.
|
/// opcodes.
|
||||||
template<typename SuperClass, unsigned Opc>
|
template<typename SuperClass, unsigned Opc>
|
||||||
|
|
|
@ -52,10 +52,10 @@ bool LLParser::ValidateEndOfModule() {
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
Instruction *Inst = I->first;
|
Instruction *Inst = I->first;
|
||||||
const std::vector<MDRef> &MDList = I->second;
|
const std::vector<MDRef> &MDList = I->second;
|
||||||
|
|
||||||
for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
|
for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
|
||||||
unsigned SlotNo = MDList[i].MDSlot;
|
unsigned SlotNo = MDList[i].MDSlot;
|
||||||
|
|
||||||
if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
|
if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
|
||||||
return Error(MDList[i].Loc, "use of undefined metadata '!" +
|
return Error(MDList[i].Loc, "use of undefined metadata '!" +
|
||||||
Twine(SlotNo) + "'");
|
Twine(SlotNo) + "'");
|
||||||
|
@ -64,8 +64,8 @@ bool LLParser::ValidateEndOfModule() {
|
||||||
}
|
}
|
||||||
ForwardRefInstMetadata.clear();
|
ForwardRefInstMetadata.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If there are entries in ForwardRefBlockAddresses at this point, they are
|
// If there are entries in ForwardRefBlockAddresses at this point, they are
|
||||||
// references after the function was defined. Resolve those now.
|
// references after the function was defined. Resolve those now.
|
||||||
while (!ForwardRefBlockAddresses.empty()) {
|
while (!ForwardRefBlockAddresses.empty()) {
|
||||||
|
@ -76,19 +76,19 @@ bool LLParser::ValidateEndOfModule() {
|
||||||
TheFn = M->getFunction(Fn.StrVal);
|
TheFn = M->getFunction(Fn.StrVal);
|
||||||
else if (Fn.UIntVal < NumberedVals.size())
|
else if (Fn.UIntVal < NumberedVals.size())
|
||||||
TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]);
|
TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]);
|
||||||
|
|
||||||
if (TheFn == 0)
|
if (TheFn == 0)
|
||||||
return Error(Fn.Loc, "unknown function referenced by blockaddress");
|
return Error(Fn.Loc, "unknown function referenced by blockaddress");
|
||||||
|
|
||||||
// Resolve all these references.
|
// Resolve all these references.
|
||||||
if (ResolveForwardRefBlockAddresses(TheFn,
|
if (ResolveForwardRefBlockAddresses(TheFn,
|
||||||
ForwardRefBlockAddresses.begin()->second,
|
ForwardRefBlockAddresses.begin()->second,
|
||||||
0))
|
0))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
|
ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
|
for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
|
||||||
if (NumberedTypes[i].second.isValid())
|
if (NumberedTypes[i].second.isValid())
|
||||||
return Error(NumberedTypes[i].second,
|
return Error(NumberedTypes[i].second,
|
||||||
|
@ -123,7 +123,7 @@ bool LLParser::ValidateEndOfModule() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
|
bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
|
||||||
std::vector<std::pair<ValID, GlobalValue*> > &Refs,
|
std::vector<std::pair<ValID, GlobalValue*> > &Refs,
|
||||||
PerFunctionState *PFS) {
|
PerFunctionState *PFS) {
|
||||||
// Loop over all the references, resolving them.
|
// Loop over all the references, resolving them.
|
||||||
|
@ -141,11 +141,11 @@ bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
|
||||||
Res = dyn_cast_or_null<BasicBlock>(
|
Res = dyn_cast_or_null<BasicBlock>(
|
||||||
TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal));
|
TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Res == 0)
|
if (Res == 0)
|
||||||
return Error(Refs[i].first.Loc,
|
return Error(Refs[i].first.Loc,
|
||||||
"referenced value is not a basic block");
|
"referenced value is not a basic block");
|
||||||
|
|
||||||
// Get the BlockAddress for this and update references to use it.
|
// Get the BlockAddress for this and update references to use it.
|
||||||
BlockAddress *BA = BlockAddress::get(TheFn, Res);
|
BlockAddress *BA = BlockAddress::get(TheFn, Res);
|
||||||
Refs[i].second->replaceAllUsesWith(BA);
|
Refs[i].second->replaceAllUsesWith(BA);
|
||||||
|
@ -302,11 +302,11 @@ bool LLParser::ParseUnnamedType() {
|
||||||
|
|
||||||
if (TypeID >= NumberedTypes.size())
|
if (TypeID >= NumberedTypes.size())
|
||||||
NumberedTypes.resize(TypeID+1);
|
NumberedTypes.resize(TypeID+1);
|
||||||
|
|
||||||
Type *Result = 0;
|
Type *Result = 0;
|
||||||
if (ParseStructDefinition(TypeLoc, "",
|
if (ParseStructDefinition(TypeLoc, "",
|
||||||
NumberedTypes[TypeID], Result)) return true;
|
NumberedTypes[TypeID], Result)) return true;
|
||||||
|
|
||||||
if (!isa<StructType>(Result)) {
|
if (!isa<StructType>(Result)) {
|
||||||
std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
|
std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
|
||||||
if (Entry.first)
|
if (Entry.first)
|
||||||
|
@ -329,11 +329,11 @@ bool LLParser::ParseNamedType() {
|
||||||
if (ParseToken(lltok::equal, "expected '=' after name") ||
|
if (ParseToken(lltok::equal, "expected '=' after name") ||
|
||||||
ParseToken(lltok::kw_type, "expected 'type' after name"))
|
ParseToken(lltok::kw_type, "expected 'type' after name"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Type *Result = 0;
|
Type *Result = 0;
|
||||||
if (ParseStructDefinition(NameLoc, Name,
|
if (ParseStructDefinition(NameLoc, Name,
|
||||||
NamedTypes[Name], Result)) return true;
|
NamedTypes[Name], Result)) return true;
|
||||||
|
|
||||||
if (!isa<StructType>(Result)) {
|
if (!isa<StructType>(Result)) {
|
||||||
std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
|
std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
|
||||||
if (Entry.first)
|
if (Entry.first)
|
||||||
|
@ -341,7 +341,7 @@ bool LLParser::ParseNamedType() {
|
||||||
Entry.first = Result;
|
Entry.first = Result;
|
||||||
Entry.second = SMLoc();
|
Entry.second = SMLoc();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) {
|
||||||
// Otherwise, create MDNode forward reference.
|
// Otherwise, create MDNode forward reference.
|
||||||
MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef<Value*>());
|
MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef<Value*>());
|
||||||
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
|
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
|
||||||
|
|
||||||
if (NumberedMetadata.size() <= MID)
|
if (NumberedMetadata.size() <= MID)
|
||||||
NumberedMetadata.resize(MID+1);
|
NumberedMetadata.resize(MID+1);
|
||||||
NumberedMetadata[MID] = FwdNode;
|
NumberedMetadata[MID] = FwdNode;
|
||||||
|
@ -498,7 +498,7 @@ bool LLParser::ParseNamedMetadata() {
|
||||||
do {
|
do {
|
||||||
if (ParseToken(lltok::exclaim, "Expected '!' here"))
|
if (ParseToken(lltok::exclaim, "Expected '!' here"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
MDNode *N = 0;
|
MDNode *N = 0;
|
||||||
if (ParseMDNodeID(N)) return true;
|
if (ParseMDNodeID(N)) return true;
|
||||||
NMD->addOperand(N);
|
NMD->addOperand(N);
|
||||||
|
@ -530,7 +530,7 @@ bool LLParser::ParseStandaloneMetadata() {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
MDNode *Init = MDNode::get(Context, Elts);
|
MDNode *Init = MDNode::get(Context, Elts);
|
||||||
|
|
||||||
// See if this was forward referenced, if so, handle it.
|
// See if this was forward referenced, if so, handle it.
|
||||||
std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator
|
std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator
|
||||||
FI = ForwardRefMDNodes.find(MetadataID);
|
FI = ForwardRefMDNodes.find(MetadataID);
|
||||||
|
@ -539,7 +539,7 @@ bool LLParser::ParseStandaloneMetadata() {
|
||||||
Temp->replaceAllUsesWith(Init);
|
Temp->replaceAllUsesWith(Init);
|
||||||
MDNode::deleteTemporary(Temp);
|
MDNode::deleteTemporary(Temp);
|
||||||
ForwardRefMDNodes.erase(FI);
|
ForwardRefMDNodes.erase(FI);
|
||||||
|
|
||||||
assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
|
assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
|
||||||
} else {
|
} else {
|
||||||
if (MetadataID >= NumberedMetadata.size())
|
if (MetadataID >= NumberedMetadata.size())
|
||||||
|
@ -1205,7 +1205,7 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseOptionalCommaAlign
|
/// ParseOptionalCommaAlign
|
||||||
/// ::=
|
/// ::=
|
||||||
/// ::= ',' align 4
|
/// ::= ',' align 4
|
||||||
///
|
///
|
||||||
/// This returns with AteExtraComma set to true if it ate an excess comma at the
|
/// This returns with AteExtraComma set to true if it ate an excess comma at the
|
||||||
|
@ -1219,7 +1219,7 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
|
||||||
AteExtraComma = true;
|
AteExtraComma = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Lex.getKind() != lltok::kw_align)
|
if (Lex.getKind() != lltok::kw_align)
|
||||||
return Error(Lex.getLoc(), "expected metadata or 'align'");
|
return Error(Lex.getLoc(), "expected metadata or 'align'");
|
||||||
|
|
||||||
|
@ -1287,7 +1287,7 @@ bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) {
|
||||||
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
|
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
|
||||||
bool &AteExtraComma) {
|
bool &AteExtraComma) {
|
||||||
AteExtraComma = false;
|
AteExtraComma = false;
|
||||||
|
|
||||||
if (Lex.getKind() != lltok::comma)
|
if (Lex.getKind() != lltok::comma)
|
||||||
return TokError("expected ',' as start of index list");
|
return TokError("expected ',' as start of index list");
|
||||||
|
|
||||||
|
@ -1343,7 +1343,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
|
||||||
case lltok::LocalVar: {
|
case lltok::LocalVar: {
|
||||||
// Type ::= %foo
|
// Type ::= %foo
|
||||||
std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()];
|
std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()];
|
||||||
|
|
||||||
// If the type hasn't been defined yet, create a forward definition and
|
// If the type hasn't been defined yet, create a forward definition and
|
||||||
// remember where that forward def'n was seen (in case it never is defined).
|
// remember where that forward def'n was seen (in case it never is defined).
|
||||||
if (Entry.first == 0) {
|
if (Entry.first == 0) {
|
||||||
|
@ -1360,7 +1360,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
|
||||||
if (Lex.getUIntVal() >= NumberedTypes.size())
|
if (Lex.getUIntVal() >= NumberedTypes.size())
|
||||||
NumberedTypes.resize(Lex.getUIntVal()+1);
|
NumberedTypes.resize(Lex.getUIntVal()+1);
|
||||||
std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];
|
std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];
|
||||||
|
|
||||||
// If the type hasn't been defined yet, create a forward definition and
|
// If the type hasn't been defined yet, create a forward definition and
|
||||||
// remember where that forward def'n was seen (in case it never is defined).
|
// remember where that forward def'n was seen (in case it never is defined).
|
||||||
if (Entry.first == 0) {
|
if (Entry.first == 0) {
|
||||||
|
@ -1569,7 +1569,7 @@ bool LLParser::ParseFunctionType(Type *&Result) {
|
||||||
bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) {
|
bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) {
|
||||||
SmallVector<Type*, 8> Elts;
|
SmallVector<Type*, 8> Elts;
|
||||||
if (ParseStructBody(Elts)) return true;
|
if (ParseStructBody(Elts)) return true;
|
||||||
|
|
||||||
Result = StructType::get(Context, Elts, Packed);
|
Result = StructType::get(Context, Elts, Packed);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1581,20 +1581,20 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name,
|
||||||
// If the type was already defined, diagnose the redefinition.
|
// If the type was already defined, diagnose the redefinition.
|
||||||
if (Entry.first && !Entry.second.isValid())
|
if (Entry.first && !Entry.second.isValid())
|
||||||
return Error(TypeLoc, "redefinition of type");
|
return Error(TypeLoc, "redefinition of type");
|
||||||
|
|
||||||
// If we have opaque, just return without filling in the definition for the
|
// If we have opaque, just return without filling in the definition for the
|
||||||
// struct. This counts as a definition as far as the .ll file goes.
|
// struct. This counts as a definition as far as the .ll file goes.
|
||||||
if (EatIfPresent(lltok::kw_opaque)) {
|
if (EatIfPresent(lltok::kw_opaque)) {
|
||||||
// This type is being defined, so clear the location to indicate this.
|
// This type is being defined, so clear the location to indicate this.
|
||||||
Entry.second = SMLoc();
|
Entry.second = SMLoc();
|
||||||
|
|
||||||
// If this type number has never been uttered, create it.
|
// If this type number has never been uttered, create it.
|
||||||
if (Entry.first == 0)
|
if (Entry.first == 0)
|
||||||
Entry.first = StructType::create(Context, Name);
|
Entry.first = StructType::create(Context, Name);
|
||||||
ResultTy = Entry.first;
|
ResultTy = Entry.first;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the type starts with '<', then it is either a packed struct or a vector.
|
// If the type starts with '<', then it is either a packed struct or a vector.
|
||||||
bool isPacked = EatIfPresent(lltok::less);
|
bool isPacked = EatIfPresent(lltok::less);
|
||||||
|
|
||||||
|
@ -1604,27 +1604,27 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name,
|
||||||
if (Lex.getKind() != lltok::lbrace) {
|
if (Lex.getKind() != lltok::lbrace) {
|
||||||
if (Entry.first)
|
if (Entry.first)
|
||||||
return Error(TypeLoc, "forward references to non-struct type");
|
return Error(TypeLoc, "forward references to non-struct type");
|
||||||
|
|
||||||
ResultTy = 0;
|
ResultTy = 0;
|
||||||
if (isPacked)
|
if (isPacked)
|
||||||
return ParseArrayVectorType(ResultTy, true);
|
return ParseArrayVectorType(ResultTy, true);
|
||||||
return ParseType(ResultTy);
|
return ParseType(ResultTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This type is being defined, so clear the location to indicate this.
|
// This type is being defined, so clear the location to indicate this.
|
||||||
Entry.second = SMLoc();
|
Entry.second = SMLoc();
|
||||||
|
|
||||||
// If this type number has never been uttered, create it.
|
// If this type number has never been uttered, create it.
|
||||||
if (Entry.first == 0)
|
if (Entry.first == 0)
|
||||||
Entry.first = StructType::create(Context, Name);
|
Entry.first = StructType::create(Context, Name);
|
||||||
|
|
||||||
StructType *STy = cast<StructType>(Entry.first);
|
StructType *STy = cast<StructType>(Entry.first);
|
||||||
|
|
||||||
SmallVector<Type*, 8> Body;
|
SmallVector<Type*, 8> Body;
|
||||||
if (ParseStructBody(Body) ||
|
if (ParseStructBody(Body) ||
|
||||||
(isPacked && ParseToken(lltok::greater, "expected '>' in packed struct")))
|
(isPacked && ParseToken(lltok::greater, "expected '>' in packed struct")))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
STy->setBody(Body, isPacked);
|
STy->setBody(Body, isPacked);
|
||||||
ResultTy = STy;
|
ResultTy = STy;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1754,18 +1754,18 @@ bool LLParser::PerFunctionState::FinishFunction() {
|
||||||
FunctionID.Kind = ValID::t_GlobalID;
|
FunctionID.Kind = ValID::t_GlobalID;
|
||||||
FunctionID.UIntVal = FunctionNumber;
|
FunctionID.UIntVal = FunctionNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator
|
std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator
|
||||||
FRBAI = P.ForwardRefBlockAddresses.find(FunctionID);
|
FRBAI = P.ForwardRefBlockAddresses.find(FunctionID);
|
||||||
if (FRBAI != P.ForwardRefBlockAddresses.end()) {
|
if (FRBAI != P.ForwardRefBlockAddresses.end()) {
|
||||||
// Resolve all these references.
|
// Resolve all these references.
|
||||||
if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this))
|
if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
P.ForwardRefBlockAddresses.erase(FRBAI);
|
P.ForwardRefBlockAddresses.erase(FRBAI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ForwardRefVals.empty())
|
if (!ForwardRefVals.empty())
|
||||||
return P.Error(ForwardRefVals.begin()->second.second,
|
return P.Error(ForwardRefVals.begin()->second.second,
|
||||||
"use of undefined value '%" + ForwardRefVals.begin()->first +
|
"use of undefined value '%" + ForwardRefVals.begin()->first +
|
||||||
|
@ -2138,19 +2138,19 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
|
||||||
|
|
||||||
ValID Fn, Label;
|
ValID Fn, Label;
|
||||||
LocTy FnLoc, LabelLoc;
|
LocTy FnLoc, LabelLoc;
|
||||||
|
|
||||||
if (ParseToken(lltok::lparen, "expected '(' in block address expression") ||
|
if (ParseToken(lltok::lparen, "expected '(' in block address expression") ||
|
||||||
ParseValID(Fn) ||
|
ParseValID(Fn) ||
|
||||||
ParseToken(lltok::comma, "expected comma in block address expression")||
|
ParseToken(lltok::comma, "expected comma in block address expression")||
|
||||||
ParseValID(Label) ||
|
ParseValID(Label) ||
|
||||||
ParseToken(lltok::rparen, "expected ')' in block address expression"))
|
ParseToken(lltok::rparen, "expected ')' in block address expression"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
|
if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
|
||||||
return Error(Fn.Loc, "expected function name in blockaddress");
|
return Error(Fn.Loc, "expected function name in blockaddress");
|
||||||
if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName)
|
if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName)
|
||||||
return Error(Label.Loc, "expected basic block name in blockaddress");
|
return Error(Label.Loc, "expected basic block name in blockaddress");
|
||||||
|
|
||||||
// Make a global variable as a placeholder for this reference.
|
// Make a global variable as a placeholder for this reference.
|
||||||
GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context),
|
GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context),
|
||||||
false, GlobalValue::InternalLinkage,
|
false, GlobalValue::InternalLinkage,
|
||||||
|
@ -2160,7 +2160,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
|
||||||
ID.Kind = ValID::t_Constant;
|
ID.Kind = ValID::t_Constant;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case lltok::kw_trunc:
|
case lltok::kw_trunc:
|
||||||
case lltok::kw_zext:
|
case lltok::kw_zext:
|
||||||
case lltok::kw_sext:
|
case lltok::kw_sext:
|
||||||
|
@ -2540,7 +2540,7 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
|
||||||
return (V == 0);
|
return (V == 0);
|
||||||
case ValID::t_InlineAsm: {
|
case ValID::t_InlineAsm: {
|
||||||
PointerType *PTy = dyn_cast<PointerType>(Ty);
|
PointerType *PTy = dyn_cast<PointerType>(Ty);
|
||||||
FunctionType *FTy =
|
FunctionType *FTy =
|
||||||
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
|
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
|
||||||
if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
|
if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
|
||||||
return Error(ID.Loc, "invalid type for inline asm constraint string");
|
return Error(ID.Loc, "invalid type for inline asm constraint string");
|
||||||
|
@ -2629,13 +2629,13 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
|
||||||
"initializer with struct type has wrong # elements");
|
"initializer with struct type has wrong # elements");
|
||||||
if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct))
|
if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct))
|
||||||
return Error(ID.Loc, "packed'ness of initializer and type don't match");
|
return Error(ID.Loc, "packed'ness of initializer and type don't match");
|
||||||
|
|
||||||
// Verify that the elements are compatible with the structtype.
|
// Verify that the elements are compatible with the structtype.
|
||||||
for (unsigned i = 0, e = ID.UIntVal; i != e; ++i)
|
for (unsigned i = 0, e = ID.UIntVal; i != e; ++i)
|
||||||
if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i))
|
if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i))
|
||||||
return Error(ID.Loc, "element " + Twine(i) +
|
return Error(ID.Loc, "element " + Twine(i) +
|
||||||
" of struct initializer doesn't match struct element type");
|
" of struct initializer doesn't match struct element type");
|
||||||
|
|
||||||
V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts,
|
V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts,
|
||||||
ID.UIntVal));
|
ID.UIntVal));
|
||||||
} else
|
} else
|
||||||
|
@ -2815,7 +2815,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
||||||
if (Fn->getType() != PFT)
|
if (Fn->getType() != PFT)
|
||||||
return Error(FRVI->second.second, "invalid forward reference to "
|
return Error(FRVI->second.second, "invalid forward reference to "
|
||||||
"function '" + FunctionName + "' with wrong type!");
|
"function '" + FunctionName + "' with wrong type!");
|
||||||
|
|
||||||
ForwardRefVals.erase(FRVI);
|
ForwardRefVals.erase(FRVI);
|
||||||
} else if ((Fn = M->getFunction(FunctionName))) {
|
} else if ((Fn = M->getFunction(FunctionName))) {
|
||||||
// Reject redefinitions.
|
// Reject redefinitions.
|
||||||
|
@ -2884,13 +2884,13 @@ bool LLParser::ParseFunctionBody(Function &Fn) {
|
||||||
|
|
||||||
int FunctionNumber = -1;
|
int FunctionNumber = -1;
|
||||||
if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1;
|
if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1;
|
||||||
|
|
||||||
PerFunctionState PFS(*this, Fn, FunctionNumber);
|
PerFunctionState PFS(*this, Fn, FunctionNumber);
|
||||||
|
|
||||||
// We need at least one basic block.
|
// We need at least one basic block.
|
||||||
if (Lex.getKind() == lltok::rbrace)
|
if (Lex.getKind() == lltok::rbrace)
|
||||||
return TokError("function body requires at least one basic block");
|
return TokError("function body requires at least one basic block");
|
||||||
|
|
||||||
while (Lex.getKind() != lltok::rbrace)
|
while (Lex.getKind() != lltok::rbrace)
|
||||||
if (ParseBasicBlock(PFS)) return true;
|
if (ParseBasicBlock(PFS)) return true;
|
||||||
|
|
||||||
|
@ -2958,7 +2958,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
|
||||||
// *must* be followed by metadata.
|
// *must* be followed by metadata.
|
||||||
if (ParseInstructionMetadata(Inst, &PFS))
|
if (ParseInstructionMetadata(Inst, &PFS))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the name on the instruction.
|
// Set the name on the instruction.
|
||||||
|
@ -3001,9 +3001,9 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
||||||
bool NUW = EatIfPresent(lltok::kw_nuw);
|
bool NUW = EatIfPresent(lltok::kw_nuw);
|
||||||
bool NSW = EatIfPresent(lltok::kw_nsw);
|
bool NSW = EatIfPresent(lltok::kw_nsw);
|
||||||
if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);
|
if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);
|
||||||
|
|
||||||
if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
|
if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
|
||||||
|
|
||||||
if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
|
if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
|
||||||
if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
|
if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
|
||||||
return false;
|
return false;
|
||||||
|
@ -3123,12 +3123,12 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
|
||||||
if (ParseType(Ty, true /*void allowed*/)) return true;
|
if (ParseType(Ty, true /*void allowed*/)) return true;
|
||||||
|
|
||||||
Type *ResType = PFS.getFunction().getReturnType();
|
Type *ResType = PFS.getFunction().getReturnType();
|
||||||
|
|
||||||
if (Ty->isVoidTy()) {
|
if (Ty->isVoidTy()) {
|
||||||
if (!ResType->isVoidTy())
|
if (!ResType->isVoidTy())
|
||||||
return Error(TypeLoc, "value doesn't match function result type '" +
|
return Error(TypeLoc, "value doesn't match function result type '" +
|
||||||
getTypeString(ResType) + "'");
|
getTypeString(ResType) + "'");
|
||||||
|
|
||||||
Inst = ReturnInst::Create(Context);
|
Inst = ReturnInst::Create(Context);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3139,7 +3139,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
|
||||||
if (ResType != RV->getType())
|
if (ResType != RV->getType())
|
||||||
return Error(TypeLoc, "value doesn't match function result type '" +
|
return Error(TypeLoc, "value doesn't match function result type '" +
|
||||||
getTypeString(ResType) + "'");
|
getTypeString(ResType) + "'");
|
||||||
|
|
||||||
Inst = ReturnInst::Create(Context, RV);
|
Inst = ReturnInst::Create(Context, RV);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3201,7 +3201,7 @@ bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
|
||||||
ParseToken(lltok::comma, "expected ',' after case value") ||
|
ParseToken(lltok::comma, "expected ',' after case value") ||
|
||||||
ParseTypeAndBasicBlock(DestBB, PFS))
|
ParseTypeAndBasicBlock(DestBB, PFS))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!SeenCases.insert(Constant))
|
if (!SeenCases.insert(Constant))
|
||||||
return Error(CondLoc, "duplicate case value in switch");
|
return Error(CondLoc, "duplicate case value in switch");
|
||||||
if (!isa<ConstantInt>(Constant))
|
if (!isa<ConstantInt>(Constant))
|
||||||
|
@ -3229,26 +3229,26 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
|
||||||
ParseToken(lltok::comma, "expected ',' after indirectbr address") ||
|
ParseToken(lltok::comma, "expected ',' after indirectbr address") ||
|
||||||
ParseToken(lltok::lsquare, "expected '[' with indirectbr"))
|
ParseToken(lltok::lsquare, "expected '[' with indirectbr"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!Address->getType()->isPointerTy())
|
if (!Address->getType()->isPointerTy())
|
||||||
return Error(AddrLoc, "indirectbr address must have pointer type");
|
return Error(AddrLoc, "indirectbr address must have pointer type");
|
||||||
|
|
||||||
// Parse the destination list.
|
// Parse the destination list.
|
||||||
SmallVector<BasicBlock*, 16> DestList;
|
SmallVector<BasicBlock*, 16> DestList;
|
||||||
|
|
||||||
if (Lex.getKind() != lltok::rsquare) {
|
if (Lex.getKind() != lltok::rsquare) {
|
||||||
BasicBlock *DestBB;
|
BasicBlock *DestBB;
|
||||||
if (ParseTypeAndBasicBlock(DestBB, PFS))
|
if (ParseTypeAndBasicBlock(DestBB, PFS))
|
||||||
return true;
|
return true;
|
||||||
DestList.push_back(DestBB);
|
DestList.push_back(DestBB);
|
||||||
|
|
||||||
while (EatIfPresent(lltok::comma)) {
|
while (EatIfPresent(lltok::comma)) {
|
||||||
if (ParseTypeAndBasicBlock(DestBB, PFS))
|
if (ParseTypeAndBasicBlock(DestBB, PFS))
|
||||||
return true;
|
return true;
|
||||||
DestList.push_back(DestBB);
|
DestList.push_back(DestBB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ParseToken(lltok::rsquare, "expected ']' at end of block list"))
|
if (ParseToken(lltok::rsquare, "expected ']' at end of block list"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -3795,7 +3795,7 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
|
||||||
|
|
||||||
/// ParseLoad
|
/// ParseLoad
|
||||||
/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)?
|
/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)?
|
||||||
/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
|
/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
|
||||||
/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
|
/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
|
||||||
int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
|
int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
|
||||||
Value *Val; LocTy Loc;
|
Value *Val; LocTy Loc;
|
||||||
|
@ -4069,7 +4069,7 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
|
||||||
ParseTypeAndValue(Val1, Loc1, PFS) ||
|
ParseTypeAndValue(Val1, Loc1, PFS) ||
|
||||||
ParseIndexList(Indices, AteExtraComma))
|
ParseIndexList(Indices, AteExtraComma))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!Val0->getType()->isAggregateType())
|
if (!Val0->getType()->isAggregateType())
|
||||||
return Error(Loc0, "insertvalue operand must be aggregate type");
|
return Error(Loc0, "insertvalue operand must be aggregate type");
|
||||||
|
|
||||||
|
@ -4099,7 +4099,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
|
||||||
Elts.push_back(0);
|
Elts.push_back(0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *V = 0;
|
Value *V = 0;
|
||||||
if (ParseTypeAndValue(V, PFS)) return true;
|
if (ParseTypeAndValue(V, PFS)) return true;
|
||||||
Elts.push_back(V);
|
Elts.push_back(V);
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace llvm {
|
||||||
t_ConstantStruct, // Value in ConstantStructElts.
|
t_ConstantStruct, // Value in ConstantStructElts.
|
||||||
t_PackedConstantStruct // Value in ConstantStructElts.
|
t_PackedConstantStruct // Value in ConstantStructElts.
|
||||||
} Kind;
|
} Kind;
|
||||||
|
|
||||||
LLLexer::LocTy Loc;
|
LLLexer::LocTy Loc;
|
||||||
unsigned UIntVal;
|
unsigned UIntVal;
|
||||||
std::string StrVal, StrVal2;
|
std::string StrVal, StrVal2;
|
||||||
|
@ -65,23 +65,23 @@ namespace llvm {
|
||||||
MDNode *MDNodeVal;
|
MDNode *MDNodeVal;
|
||||||
MDString *MDStringVal;
|
MDString *MDStringVal;
|
||||||
Constant **ConstantStructElts;
|
Constant **ConstantStructElts;
|
||||||
|
|
||||||
ValID() : Kind(t_LocalID), APFloatVal(0.0) {}
|
ValID() : Kind(t_LocalID), APFloatVal(0.0) {}
|
||||||
~ValID() {
|
~ValID() {
|
||||||
if (Kind == t_ConstantStruct || Kind == t_PackedConstantStruct)
|
if (Kind == t_ConstantStruct || Kind == t_PackedConstantStruct)
|
||||||
delete [] ConstantStructElts;
|
delete [] ConstantStructElts;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const ValID &RHS) const {
|
bool operator<(const ValID &RHS) const {
|
||||||
if (Kind == t_LocalID || Kind == t_GlobalID)
|
if (Kind == t_LocalID || Kind == t_GlobalID)
|
||||||
return UIntVal < RHS.UIntVal;
|
return UIntVal < RHS.UIntVal;
|
||||||
assert((Kind == t_LocalName || Kind == t_GlobalName ||
|
assert((Kind == t_LocalName || Kind == t_GlobalName ||
|
||||||
Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) &&
|
Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) &&
|
||||||
"Ordering not defined for this ValID kind yet");
|
"Ordering not defined for this ValID kind yet");
|
||||||
return StrVal < RHS.StrVal;
|
return StrVal < RHS.StrVal;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLParser {
|
class LLParser {
|
||||||
public:
|
public:
|
||||||
typedef LLLexer::LocTy LocTy;
|
typedef LLLexer::LocTy LocTy;
|
||||||
|
@ -89,7 +89,7 @@ namespace llvm {
|
||||||
LLVMContext &Context;
|
LLVMContext &Context;
|
||||||
LLLexer Lex;
|
LLLexer Lex;
|
||||||
Module *M;
|
Module *M;
|
||||||
|
|
||||||
// Instruction metadata resolution. Each instruction can have a list of
|
// Instruction metadata resolution. Each instruction can have a list of
|
||||||
// MDRef info associated with them.
|
// MDRef info associated with them.
|
||||||
//
|
//
|
||||||
|
@ -110,7 +110,7 @@ namespace llvm {
|
||||||
// have processed a use of the type but not a definition yet.
|
// have processed a use of the type but not a definition yet.
|
||||||
StringMap<std::pair<Type*, LocTy> > NamedTypes;
|
StringMap<std::pair<Type*, LocTy> > NamedTypes;
|
||||||
std::vector<std::pair<Type*, LocTy> > NumberedTypes;
|
std::vector<std::pair<Type*, LocTy> > NumberedTypes;
|
||||||
|
|
||||||
std::vector<TrackingVH<MDNode> > NumberedMetadata;
|
std::vector<TrackingVH<MDNode> > NumberedMetadata;
|
||||||
std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> > ForwardRefMDNodes;
|
std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> > ForwardRefMDNodes;
|
||||||
|
|
||||||
|
@ -118,14 +118,14 @@ namespace llvm {
|
||||||
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
|
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
|
||||||
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
|
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
|
||||||
std::vector<GlobalValue*> NumberedVals;
|
std::vector<GlobalValue*> NumberedVals;
|
||||||
|
|
||||||
// References to blockaddress. The key is the function ValID, the value is
|
// References to blockaddress. The key is the function ValID, the value is
|
||||||
// a list of references to blocks in that function.
|
// a list of references to blocks in that function.
|
||||||
std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >
|
std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >
|
||||||
ForwardRefBlockAddresses;
|
ForwardRefBlockAddresses;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
|
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
|
||||||
Context(m->getContext()), Lex(F, SM, Err, m->getContext()),
|
Context(m->getContext()), Lex(F, SM, Err, m->getContext()),
|
||||||
M(m) {}
|
M(m) {}
|
||||||
bool Run();
|
bool Run();
|
||||||
|
@ -241,7 +241,7 @@ namespace llvm {
|
||||||
std::map<std::string, std::pair<Value*, LocTy> > ForwardRefVals;
|
std::map<std::string, std::pair<Value*, LocTy> > ForwardRefVals;
|
||||||
std::map<unsigned, std::pair<Value*, LocTy> > ForwardRefValIDs;
|
std::map<unsigned, std::pair<Value*, LocTy> > ForwardRefValIDs;
|
||||||
std::vector<Value*> NumberedVals;
|
std::vector<Value*> NumberedVals;
|
||||||
|
|
||||||
/// FunctionNumber - If this is an unnamed function, this is the slot
|
/// FunctionNumber - If this is an unnamed function, this is the slot
|
||||||
/// number of it, otherwise it is -1.
|
/// number of it, otherwise it is -1.
|
||||||
int FunctionNumber;
|
int FunctionNumber;
|
||||||
|
@ -375,8 +375,8 @@ namespace llvm {
|
||||||
int ParseGetElementPtr(Instruction *&I, PerFunctionState &PFS);
|
int ParseGetElementPtr(Instruction *&I, PerFunctionState &PFS);
|
||||||
int ParseExtractValue(Instruction *&I, PerFunctionState &PFS);
|
int ParseExtractValue(Instruction *&I, PerFunctionState &PFS);
|
||||||
int ParseInsertValue(Instruction *&I, PerFunctionState &PFS);
|
int ParseInsertValue(Instruction *&I, PerFunctionState &PFS);
|
||||||
|
|
||||||
bool ResolveForwardRefBlockAddresses(Function *TheFn,
|
bool ResolveForwardRefBlockAddresses(Function *TheFn,
|
||||||
std::vector<std::pair<ValID, GlobalValue*> > &Refs,
|
std::vector<std::pair<ValID, GlobalValue*> > &Refs,
|
||||||
PerFunctionState *PFS);
|
PerFunctionState *PFS);
|
||||||
};
|
};
|
||||||
|
|
|
@ -607,7 +607,7 @@ bool BitcodeReader::ParseTypeTableBody() {
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultTy = getTypeByID(Record[2]);
|
ResultTy = getTypeByID(Record[2]);
|
||||||
if (ResultTy == 0 || ArgTys.size() < Record.size()-3)
|
if (ResultTy == 0 || ArgTys.size() < Record.size()-3)
|
||||||
return Error("invalid type in function type");
|
return Error("invalid type in function type");
|
||||||
|
@ -626,7 +626,7 @@ bool BitcodeReader::ParseTypeTableBody() {
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultTy = getTypeByID(Record[1]);
|
ResultTy = getTypeByID(Record[1]);
|
||||||
if (ResultTy == 0 || ArgTys.size() < Record.size()-2)
|
if (ResultTy == 0 || ArgTys.size() < Record.size()-2)
|
||||||
return Error("invalid type in function type");
|
return Error("invalid type in function type");
|
||||||
|
@ -657,10 +657,10 @@ bool BitcodeReader::ParseTypeTableBody() {
|
||||||
case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
|
case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
|
||||||
if (Record.size() < 1)
|
if (Record.size() < 1)
|
||||||
return Error("Invalid STRUCT type record");
|
return Error("Invalid STRUCT type record");
|
||||||
|
|
||||||
if (NumRecords >= TypeList.size())
|
if (NumRecords >= TypeList.size())
|
||||||
return Error("invalid TYPE table");
|
return Error("invalid TYPE table");
|
||||||
|
|
||||||
// Check to see if this was forward referenced, if so fill in the temp.
|
// Check to see if this was forward referenced, if so fill in the temp.
|
||||||
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
|
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
|
||||||
if (Res) {
|
if (Res) {
|
||||||
|
@ -669,7 +669,7 @@ bool BitcodeReader::ParseTypeTableBody() {
|
||||||
} else // Otherwise, create a new struct.
|
} else // Otherwise, create a new struct.
|
||||||
Res = StructType::create(Context, TypeName);
|
Res = StructType::create(Context, TypeName);
|
||||||
TypeName.clear();
|
TypeName.clear();
|
||||||
|
|
||||||
SmallVector<Type*, 8> EltTys;
|
SmallVector<Type*, 8> EltTys;
|
||||||
for (unsigned i = 1, e = Record.size(); i != e; ++i) {
|
for (unsigned i = 1, e = Record.size(); i != e; ++i) {
|
||||||
if (Type *T = getTypeByID(Record[i]))
|
if (Type *T = getTypeByID(Record[i]))
|
||||||
|
@ -689,7 +689,7 @@ bool BitcodeReader::ParseTypeTableBody() {
|
||||||
|
|
||||||
if (NumRecords >= TypeList.size())
|
if (NumRecords >= TypeList.size())
|
||||||
return Error("invalid TYPE table");
|
return Error("invalid TYPE table");
|
||||||
|
|
||||||
// Check to see if this was forward referenced, if so fill in the temp.
|
// Check to see if this was forward referenced, if so fill in the temp.
|
||||||
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
|
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
|
||||||
if (Res) {
|
if (Res) {
|
||||||
|
@ -700,7 +700,7 @@ bool BitcodeReader::ParseTypeTableBody() {
|
||||||
TypeName.clear();
|
TypeName.clear();
|
||||||
ResultTy = Res;
|
ResultTy = Res;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
|
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
|
||||||
if (Record.size() < 2)
|
if (Record.size() < 2)
|
||||||
return Error("Invalid ARRAY type record");
|
return Error("Invalid ARRAY type record");
|
||||||
|
@ -1006,7 +1006,7 @@ bool BitcodeReader::ParseConstants() {
|
||||||
APInt VInt = ReadWideAPInt(Record,
|
APInt VInt = ReadWideAPInt(Record,
|
||||||
cast<IntegerType>(CurTy)->getBitWidth());
|
cast<IntegerType>(CurTy)->getBitWidth());
|
||||||
V = ConstantInt::get(Context, VInt);
|
V = ConstantInt::get(Context, VInt);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
|
case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
|
||||||
|
@ -1073,10 +1073,10 @@ bool BitcodeReader::ParseConstants() {
|
||||||
case bitc::CST_CODE_DATA: {// DATA: [n x value]
|
case bitc::CST_CODE_DATA: {// DATA: [n x value]
|
||||||
if (Record.empty())
|
if (Record.empty())
|
||||||
return Error("Invalid CST_DATA record");
|
return Error("Invalid CST_DATA record");
|
||||||
|
|
||||||
Type *EltTy = cast<SequentialType>(CurTy)->getElementType();
|
Type *EltTy = cast<SequentialType>(CurTy)->getElementType();
|
||||||
unsigned Size = Record.size();
|
unsigned Size = Record.size();
|
||||||
|
|
||||||
if (EltTy->isIntegerTy(8)) {
|
if (EltTy->isIntegerTy(8)) {
|
||||||
SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end());
|
SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end());
|
||||||
if (isa<VectorType>(CurTy))
|
if (isa<VectorType>(CurTy))
|
||||||
|
@ -1324,7 +1324,7 @@ bool BitcodeReader::ParseConstants() {
|
||||||
V = FwdRef;
|
V = FwdRef;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueList.AssignValue(V, NextCstNo);
|
ValueList.AssignValue(V, NextCstNo);
|
||||||
|
@ -1348,7 +1348,7 @@ bool BitcodeReader::ParseUseLists() {
|
||||||
return Error("Malformed block record");
|
return Error("Malformed block record");
|
||||||
|
|
||||||
SmallVector<uint64_t, 64> Record;
|
SmallVector<uint64_t, 64> Record;
|
||||||
|
|
||||||
// Read all the records.
|
// Read all the records.
|
||||||
while (1) {
|
while (1) {
|
||||||
unsigned Code = Stream.ReadCode();
|
unsigned Code = Stream.ReadCode();
|
||||||
|
@ -1357,7 +1357,7 @@ bool BitcodeReader::ParseUseLists() {
|
||||||
return Error("Error at end of use-list table block");
|
return Error("Error at end of use-list table block");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Code == bitc::ENTER_SUBBLOCK) {
|
if (Code == bitc::ENTER_SUBBLOCK) {
|
||||||
// No known subblocks, always skip them.
|
// No known subblocks, always skip them.
|
||||||
Stream.ReadSubBlockID();
|
Stream.ReadSubBlockID();
|
||||||
|
@ -1365,12 +1365,12 @@ bool BitcodeReader::ParseUseLists() {
|
||||||
return Error("Malformed block record");
|
return Error("Malformed block record");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Code == bitc::DEFINE_ABBREV) {
|
if (Code == bitc::DEFINE_ABBREV) {
|
||||||
Stream.ReadAbbrevRecord();
|
Stream.ReadAbbrevRecord();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a use list record.
|
// Read a use list record.
|
||||||
Record.clear();
|
Record.clear();
|
||||||
switch (Stream.ReadRecord(Code, Record)) {
|
switch (Stream.ReadRecord(Code, Record)) {
|
||||||
|
@ -1919,7 +1919,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
unsigned CurBBNo = 0;
|
unsigned CurBBNo = 0;
|
||||||
|
|
||||||
DebugLoc LastLoc;
|
DebugLoc LastLoc;
|
||||||
|
|
||||||
// Read all the records.
|
// Read all the records.
|
||||||
SmallVector<uint64_t, 64> Record;
|
SmallVector<uint64_t, 64> Record;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -1974,24 +1974,24 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
FunctionBBs[i] = BasicBlock::Create(Context, "", F);
|
FunctionBBs[i] = BasicBlock::Create(Context, "", F);
|
||||||
CurBB = FunctionBBs[0];
|
CurBB = FunctionBBs[0];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN
|
case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN
|
||||||
// This record indicates that the last instruction is at the same
|
// This record indicates that the last instruction is at the same
|
||||||
// location as the previous instruction with a location.
|
// location as the previous instruction with a location.
|
||||||
I = 0;
|
I = 0;
|
||||||
|
|
||||||
// Get the last instruction emitted.
|
// Get the last instruction emitted.
|
||||||
if (CurBB && !CurBB->empty())
|
if (CurBB && !CurBB->empty())
|
||||||
I = &CurBB->back();
|
I = &CurBB->back();
|
||||||
else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
|
else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
|
||||||
!FunctionBBs[CurBBNo-1]->empty())
|
!FunctionBBs[CurBBNo-1]->empty())
|
||||||
I = &FunctionBBs[CurBBNo-1]->back();
|
I = &FunctionBBs[CurBBNo-1]->back();
|
||||||
|
|
||||||
if (I == 0) return Error("Invalid DEBUG_LOC_AGAIN record");
|
if (I == 0) return Error("Invalid DEBUG_LOC_AGAIN record");
|
||||||
I->setDebugLoc(LastLoc);
|
I->setDebugLoc(LastLoc);
|
||||||
I = 0;
|
I = 0;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
|
case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
|
||||||
I = 0; // Get the last instruction emitted.
|
I = 0; // Get the last instruction emitted.
|
||||||
if (CurBB && !CurBB->empty())
|
if (CurBB && !CurBB->empty())
|
||||||
|
@ -2001,10 +2001,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
I = &FunctionBBs[CurBBNo-1]->back();
|
I = &FunctionBBs[CurBBNo-1]->back();
|
||||||
if (I == 0 || Record.size() < 4)
|
if (I == 0 || Record.size() < 4)
|
||||||
return Error("Invalid FUNC_CODE_DEBUG_LOC record");
|
return Error("Invalid FUNC_CODE_DEBUG_LOC record");
|
||||||
|
|
||||||
unsigned Line = Record[0], Col = Record[1];
|
unsigned Line = Record[0], Col = Record[1];
|
||||||
unsigned ScopeID = Record[2], IAID = Record[3];
|
unsigned ScopeID = Record[2], IAID = Record[3];
|
||||||
|
|
||||||
MDNode *Scope = 0, *IA = 0;
|
MDNode *Scope = 0, *IA = 0;
|
||||||
if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
|
if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
|
||||||
if (IAID) IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
|
if (IAID) IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
|
||||||
|
@ -2272,10 +2272,10 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
|
case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
|
||||||
// Check magic
|
// Check magic
|
||||||
if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
|
if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
|
||||||
// New SwitchInst format with case ranges.
|
// New SwitchInst format with case ranges.
|
||||||
|
|
||||||
Type *OpTy = getTypeByID(Record[1]);
|
Type *OpTy = getTypeByID(Record[1]);
|
||||||
unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
|
unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
|
||||||
|
|
||||||
|
@ -2285,17 +2285,17 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
return Error("Invalid SWITCH record");
|
return Error("Invalid SWITCH record");
|
||||||
|
|
||||||
unsigned NumCases = Record[4];
|
unsigned NumCases = Record[4];
|
||||||
|
|
||||||
SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
|
SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
|
||||||
InstructionList.push_back(SI);
|
InstructionList.push_back(SI);
|
||||||
|
|
||||||
unsigned CurIdx = 5;
|
unsigned CurIdx = 5;
|
||||||
for (unsigned i = 0; i != NumCases; ++i) {
|
for (unsigned i = 0; i != NumCases; ++i) {
|
||||||
IntegersSubsetToBB CaseBuilder;
|
IntegersSubsetToBB CaseBuilder;
|
||||||
unsigned NumItems = Record[CurIdx++];
|
unsigned NumItems = Record[CurIdx++];
|
||||||
for (unsigned ci = 0; ci != NumItems; ++ci) {
|
for (unsigned ci = 0; ci != NumItems; ++ci) {
|
||||||
bool isSingleNumber = Record[CurIdx++];
|
bool isSingleNumber = Record[CurIdx++];
|
||||||
|
|
||||||
APInt Low;
|
APInt Low;
|
||||||
unsigned ActiveWords = 1;
|
unsigned ActiveWords = 1;
|
||||||
if (ValueBitWidth > 64)
|
if (ValueBitWidth > 64)
|
||||||
|
@ -2311,7 +2311,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
APInt High =
|
APInt High =
|
||||||
ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
|
ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
|
||||||
ValueBitWidth);
|
ValueBitWidth);
|
||||||
|
|
||||||
CaseBuilder.add(IntItem::fromType(OpTy, Low),
|
CaseBuilder.add(IntItem::fromType(OpTy, Low),
|
||||||
IntItem::fromType(OpTy, High));
|
IntItem::fromType(OpTy, High));
|
||||||
CurIdx += ActiveWords;
|
CurIdx += ActiveWords;
|
||||||
|
@ -2319,7 +2319,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
CaseBuilder.add(IntItem::fromType(OpTy, Low));
|
CaseBuilder.add(IntItem::fromType(OpTy, Low));
|
||||||
}
|
}
|
||||||
BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
|
BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
|
||||||
IntegersSubset Case = CaseBuilder.getCase();
|
IntegersSubset Case = CaseBuilder.getCase();
|
||||||
SI->addCase(Case, DestBB);
|
SI->addCase(Case, DestBB);
|
||||||
}
|
}
|
||||||
uint16_t Hash = SI->hash();
|
uint16_t Hash = SI->hash();
|
||||||
|
@ -2328,9 +2328,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
I = SI;
|
I = SI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Old SwitchInst format without case ranges.
|
// Old SwitchInst format without case ranges.
|
||||||
|
|
||||||
if (Record.size() < 3 || (Record.size() & 1) == 0)
|
if (Record.size() < 3 || (Record.size() & 1) == 0)
|
||||||
return Error("Invalid SWITCH record");
|
return Error("Invalid SWITCH record");
|
||||||
Type *OpTy = getTypeByID(Record[0]);
|
Type *OpTy = getTypeByID(Record[0]);
|
||||||
|
@ -2375,7 +2375,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
I = IBI;
|
I = IBI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case bitc::FUNC_CODE_INST_INVOKE: {
|
case bitc::FUNC_CODE_INST_INVOKE: {
|
||||||
// INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
|
// INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
|
||||||
if (Record.size() < 4) return Error("Invalid INVOKE record");
|
if (Record.size() < 4) return Error("Invalid INVOKE record");
|
||||||
|
@ -2534,7 +2534,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
|
||||||
OpNum+4 != Record.size())
|
OpNum+4 != Record.size())
|
||||||
return Error("Invalid LOADATOMIC record");
|
return Error("Invalid LOADATOMIC record");
|
||||||
|
|
||||||
|
|
||||||
AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
|
AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
|
||||||
if (Ordering == NotAtomic || Ordering == Release ||
|
if (Ordering == NotAtomic || Ordering == Release ||
|
||||||
|
@ -2750,15 +2750,15 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||||
unsigned BlockIdx = RefList[i].first;
|
unsigned BlockIdx = RefList[i].first;
|
||||||
if (BlockIdx >= FunctionBBs.size())
|
if (BlockIdx >= FunctionBBs.size())
|
||||||
return Error("Invalid blockaddress block #");
|
return Error("Invalid blockaddress block #");
|
||||||
|
|
||||||
GlobalVariable *FwdRef = RefList[i].second;
|
GlobalVariable *FwdRef = RefList[i].second;
|
||||||
FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
|
FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
|
||||||
FwdRef->eraseFromParent();
|
FwdRef->eraseFromParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockAddrFwdRefs.erase(BAFRI);
|
BlockAddrFwdRefs.erase(BAFRI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim the value list down to the size it was before we parsed this function.
|
// Trim the value list down to the size it was before we parsed this function.
|
||||||
ValueList.shrinkTo(ModuleValueListSize);
|
ValueList.shrinkTo(ModuleValueListSize);
|
||||||
MDValueList.shrinkTo(ModuleMDValueListSize);
|
MDValueList.shrinkTo(ModuleMDValueListSize);
|
||||||
|
|
|
@ -61,7 +61,7 @@ enum {
|
||||||
FUNCTION_INST_RET_VOID_ABBREV,
|
FUNCTION_INST_RET_VOID_ABBREV,
|
||||||
FUNCTION_INST_RET_VAL_ABBREV,
|
FUNCTION_INST_RET_VAL_ABBREV,
|
||||||
FUNCTION_INST_UNREACHABLE_ABBREV,
|
FUNCTION_INST_UNREACHABLE_ABBREV,
|
||||||
|
|
||||||
// SwitchInst Magic
|
// SwitchInst Magic
|
||||||
SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
|
SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
|
||||||
};
|
};
|
||||||
|
@ -234,7 +234,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
||||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
|
||||||
|
|
||||||
unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
|
unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
|
||||||
|
|
||||||
// Abbrev for TYPE_CODE_ARRAY.
|
// Abbrev for TYPE_CODE_ARRAY.
|
||||||
Abbv = new BitCodeAbbrev();
|
Abbv = new BitCodeAbbrev();
|
||||||
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
|
Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
|
||||||
|
@ -300,7 +300,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
||||||
for (StructType::element_iterator I = ST->element_begin(),
|
for (StructType::element_iterator I = ST->element_begin(),
|
||||||
E = ST->element_end(); I != E; ++I)
|
E = ST->element_end(); I != E; ++I)
|
||||||
TypeVals.push_back(VE.getTypeID(*I));
|
TypeVals.push_back(VE.getTypeID(*I));
|
||||||
|
|
||||||
if (ST->isLiteral()) {
|
if (ST->isLiteral()) {
|
||||||
Code = bitc::TYPE_CODE_STRUCT_ANON;
|
Code = bitc::TYPE_CODE_STRUCT_ANON;
|
||||||
AbbrevToUse = StructAnonAbbrev;
|
AbbrevToUse = StructAnonAbbrev;
|
||||||
|
@ -658,7 +658,7 @@ static void WriteFunctionLocalMetadata(const Function &F,
|
||||||
}
|
}
|
||||||
WriteMDNode(N, VE, Stream, Record);
|
WriteMDNode(N, VE, Stream, Record);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StartedMetadataBlock)
|
if (StartedMetadataBlock)
|
||||||
Stream.ExitBlock();
|
Stream.ExitBlock();
|
||||||
}
|
}
|
||||||
|
@ -673,18 +673,18 @@ static void WriteMetadataAttachment(const Function &F,
|
||||||
// Write metadata attachments
|
// Write metadata attachments
|
||||||
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
|
// METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
|
||||||
SmallVector<std::pair<unsigned, MDNode*>, 4> MDs;
|
SmallVector<std::pair<unsigned, MDNode*>, 4> MDs;
|
||||||
|
|
||||||
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
||||||
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
|
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
MDs.clear();
|
MDs.clear();
|
||||||
I->getAllMetadataOtherThanDebugLoc(MDs);
|
I->getAllMetadataOtherThanDebugLoc(MDs);
|
||||||
|
|
||||||
// If no metadata, ignore instruction.
|
// If no metadata, ignore instruction.
|
||||||
if (MDs.empty()) continue;
|
if (MDs.empty()) continue;
|
||||||
|
|
||||||
Record.push_back(VE.getInstructionID(I));
|
Record.push_back(VE.getInstructionID(I));
|
||||||
|
|
||||||
for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
|
||||||
Record.push_back(MDs[i].first);
|
Record.push_back(MDs[i].first);
|
||||||
Record.push_back(VE.getValueID(MDs[i].second));
|
Record.push_back(VE.getValueID(MDs[i].second));
|
||||||
|
@ -703,16 +703,16 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
|
||||||
// METADATA_KIND - [n x [id, name]]
|
// METADATA_KIND - [n x [id, name]]
|
||||||
SmallVector<StringRef, 4> Names;
|
SmallVector<StringRef, 4> Names;
|
||||||
M->getMDKindNames(Names);
|
M->getMDKindNames(Names);
|
||||||
|
|
||||||
if (Names.empty()) return;
|
if (Names.empty()) return;
|
||||||
|
|
||||||
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
||||||
|
|
||||||
for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
|
for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
|
||||||
Record.push_back(MDKindID);
|
Record.push_back(MDKindID);
|
||||||
StringRef KName = Names[MDKindID];
|
StringRef KName = Names[MDKindID];
|
||||||
Record.append(KName.begin(), KName.end());
|
Record.append(KName.begin(), KName.end());
|
||||||
|
|
||||||
Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
|
Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
|
||||||
Record.clear();
|
Record.clear();
|
||||||
}
|
}
|
||||||
|
@ -743,10 +743,10 @@ static void EmitAPInt(SmallVectorImpl<uint64_t> &Vals,
|
||||||
// format it is likely that the high bits are going to be zero.
|
// format it is likely that the high bits are going to be zero.
|
||||||
// So, we only write the number of active words.
|
// So, we only write the number of active words.
|
||||||
unsigned NWords = Val.getActiveWords();
|
unsigned NWords = Val.getActiveWords();
|
||||||
|
|
||||||
if (EmitSizeForWideNumbers)
|
if (EmitSizeForWideNumbers)
|
||||||
Vals.push_back(NWords);
|
Vals.push_back(NWords);
|
||||||
|
|
||||||
const uint64_t *RawWords = Val.getRawData();
|
const uint64_t *RawWords = Val.getRawData();
|
||||||
for (unsigned i = 0; i != NWords; ++i) {
|
for (unsigned i = 0; i != NWords; ++i) {
|
||||||
emitSignedInt64(Vals, RawWords[i]);
|
emitSignedInt64(Vals, RawWords[i]);
|
||||||
|
@ -881,12 +881,12 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
||||||
if (isCStrChar6)
|
if (isCStrChar6)
|
||||||
isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
|
isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCStrChar6)
|
if (isCStrChar6)
|
||||||
AbbrevToUse = CString6Abbrev;
|
AbbrevToUse = CString6Abbrev;
|
||||||
else if (isCStr7)
|
else if (isCStr7)
|
||||||
AbbrevToUse = CString7Abbrev;
|
AbbrevToUse = CString7Abbrev;
|
||||||
} else if (const ConstantDataSequential *CDS =
|
} else if (const ConstantDataSequential *CDS =
|
||||||
dyn_cast<ConstantDataSequential>(C)) {
|
dyn_cast<ConstantDataSequential>(C)) {
|
||||||
Code = bitc::CST_CODE_DATA;
|
Code = bitc::CST_CODE_DATA;
|
||||||
Type *EltTy = CDS->getType()->getElementType();
|
Type *EltTy = CDS->getType()->getElementType();
|
||||||
|
@ -1179,13 +1179,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||||
// Redefine Vals, since here we need to use 64 bit values
|
// Redefine Vals, since here we need to use 64 bit values
|
||||||
// explicitly to store large APInt numbers.
|
// explicitly to store large APInt numbers.
|
||||||
SmallVector<uint64_t, 128> Vals64;
|
SmallVector<uint64_t, 128> Vals64;
|
||||||
|
|
||||||
Code = bitc::FUNC_CODE_INST_SWITCH;
|
Code = bitc::FUNC_CODE_INST_SWITCH;
|
||||||
SwitchInst &SI = cast<SwitchInst>(I);
|
SwitchInst &SI = cast<SwitchInst>(I);
|
||||||
|
|
||||||
uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16);
|
uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16);
|
||||||
Vals64.push_back(SwitchRecordHeader);
|
Vals64.push_back(SwitchRecordHeader);
|
||||||
|
|
||||||
Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
|
Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
|
||||||
pushValue64(SI.getCondition(), InstID, Vals64, VE);
|
pushValue64(SI.getCondition(), InstID, Vals64, VE);
|
||||||
Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
|
Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
|
||||||
|
@ -1194,21 +1194,21 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
IntegersSubset& CaseRanges = i.getCaseValueEx();
|
IntegersSubset& CaseRanges = i.getCaseValueEx();
|
||||||
unsigned Code, Abbrev; // will unused.
|
unsigned Code, Abbrev; // will unused.
|
||||||
|
|
||||||
if (CaseRanges.isSingleNumber()) {
|
if (CaseRanges.isSingleNumber()) {
|
||||||
Vals64.push_back(1/*NumItems = 1*/);
|
Vals64.push_back(1/*NumItems = 1*/);
|
||||||
Vals64.push_back(true/*IsSingleNumber = true*/);
|
Vals64.push_back(true/*IsSingleNumber = true*/);
|
||||||
EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
|
EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Vals64.push_back(CaseRanges.getNumItems());
|
Vals64.push_back(CaseRanges.getNumItems());
|
||||||
|
|
||||||
if (CaseRanges.isSingleNumbersOnly()) {
|
if (CaseRanges.isSingleNumbersOnly()) {
|
||||||
for (unsigned ri = 0, rn = CaseRanges.getNumItems();
|
for (unsigned ri = 0, rn = CaseRanges.getNumItems();
|
||||||
ri != rn; ++ri) {
|
ri != rn; ++ri) {
|
||||||
|
|
||||||
Vals64.push_back(true/*IsSingleNumber = true*/);
|
Vals64.push_back(true/*IsSingleNumber = true*/);
|
||||||
|
|
||||||
EmitAPInt(Vals64, Code, Abbrev,
|
EmitAPInt(Vals64, Code, Abbrev,
|
||||||
CaseRanges.getSingleNumber(ri), true);
|
CaseRanges.getSingleNumber(ri), true);
|
||||||
}
|
}
|
||||||
|
@ -1217,9 +1217,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||||
ri != rn; ++ri) {
|
ri != rn; ++ri) {
|
||||||
IntegersSubset::Range r = CaseRanges.getItem(ri);
|
IntegersSubset::Range r = CaseRanges.getItem(ri);
|
||||||
bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
|
bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
|
||||||
|
|
||||||
Vals64.push_back(IsSingleNumber);
|
Vals64.push_back(IsSingleNumber);
|
||||||
|
|
||||||
EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
|
EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
|
||||||
if (!IsSingleNumber)
|
if (!IsSingleNumber)
|
||||||
EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
|
EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
|
||||||
|
@ -1227,9 +1227,9 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||||
}
|
}
|
||||||
Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
|
Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.EmitRecord(Code, Vals64, AbbrevToUse);
|
Stream.EmitRecord(Code, Vals64, AbbrevToUse);
|
||||||
|
|
||||||
// Also do expected action - clear external Vals collection:
|
// Also do expected action - clear external Vals collection:
|
||||||
Vals.clear();
|
Vals.clear();
|
||||||
return;
|
return;
|
||||||
|
@ -1243,7 +1243,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||||
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
|
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
|
||||||
Vals.push_back(VE.getValueID(I.getOperand(i)));
|
Vals.push_back(VE.getValueID(I.getOperand(i)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction::Invoke: {
|
case Instruction::Invoke: {
|
||||||
const InvokeInst *II = cast<InvokeInst>(&I);
|
const InvokeInst *II = cast<InvokeInst>(&I);
|
||||||
const Value *Callee(II->getCalledValue());
|
const Value *Callee(II->getCalledValue());
|
||||||
|
@ -1502,21 +1502,21 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
|
||||||
unsigned InstID = CstEnd;
|
unsigned InstID = CstEnd;
|
||||||
|
|
||||||
bool NeedsMetadataAttachment = false;
|
bool NeedsMetadataAttachment = false;
|
||||||
|
|
||||||
DebugLoc LastDL;
|
DebugLoc LastDL;
|
||||||
|
|
||||||
// Finally, emit all the instructions, in order.
|
// Finally, emit all the instructions, in order.
|
||||||
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
||||||
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
|
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
WriteInstruction(*I, InstID, VE, Stream, Vals);
|
WriteInstruction(*I, InstID, VE, Stream, Vals);
|
||||||
|
|
||||||
if (!I->getType()->isVoidTy())
|
if (!I->getType()->isVoidTy())
|
||||||
++InstID;
|
++InstID;
|
||||||
|
|
||||||
// If the instruction has metadata, write a metadata attachment later.
|
// If the instruction has metadata, write a metadata attachment later.
|
||||||
NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
|
NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
|
||||||
|
|
||||||
// If the instruction has a debug location, emit it.
|
// If the instruction has a debug location, emit it.
|
||||||
DebugLoc DL = I->getDebugLoc();
|
DebugLoc DL = I->getDebugLoc();
|
||||||
if (DL.isUnknown()) {
|
if (DL.isUnknown()) {
|
||||||
|
@ -1527,14 +1527,14 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
|
||||||
} else {
|
} else {
|
||||||
MDNode *Scope, *IA;
|
MDNode *Scope, *IA;
|
||||||
DL.getScopeAndInlinedAt(Scope, IA, I->getContext());
|
DL.getScopeAndInlinedAt(Scope, IA, I->getContext());
|
||||||
|
|
||||||
Vals.push_back(DL.getLine());
|
Vals.push_back(DL.getLine());
|
||||||
Vals.push_back(DL.getCol());
|
Vals.push_back(DL.getCol());
|
||||||
Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0);
|
Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0);
|
||||||
Vals.push_back(IA ? VE.getValueID(IA)+1 : 0);
|
Vals.push_back(IA ? VE.getValueID(IA)+1 : 0);
|
||||||
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
|
Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
|
||||||
Vals.clear();
|
Vals.clear();
|
||||||
|
|
||||||
LastDL = DL;
|
LastDL = DL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1709,7 +1709,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
||||||
Stream.ExitBlock();
|
Stream.ExitBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the Users based on the order in which the reader parses the bitcode
|
// Sort the Users based on the order in which the reader parses the bitcode
|
||||||
// file.
|
// file.
|
||||||
static bool bitcodereader_order(const User *lhs, const User *rhs) {
|
static bool bitcodereader_order(const User *lhs, const User *rhs) {
|
||||||
// TODO: Implement.
|
// TODO: Implement.
|
||||||
|
@ -1778,9 +1778,9 @@ static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE,
|
||||||
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
|
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
I->removeDeadConstantUsers();
|
I->removeDeadConstantUsers();
|
||||||
|
|
||||||
// Write the global variables.
|
// Write the global variables.
|
||||||
for (Module::const_global_iterator GI = M->global_begin(),
|
for (Module::const_global_iterator GI = M->global_begin(),
|
||||||
GE = M->global_end(); GI != GE; ++GI) {
|
GE = M->global_end(); GI != GE; ++GI) {
|
||||||
WriteUseList(GI, VE, Stream);
|
WriteUseList(GI, VE, Stream);
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out)
|
||||||
default: Out << "cc" << cc; break;
|
default: Out << "cc" << cc; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintEscapedString - Print each character of the specified string, escaping
|
// PrintEscapedString - Print each character of the specified string, escaping
|
||||||
// it if it is not printable or if it is an escape char.
|
// it if it is not printable or if it is an escape char.
|
||||||
static void PrintEscapedString(StringRef Name, raw_ostream &Out) {
|
static void PrintEscapedString(StringRef Name, raw_ostream &Out) {
|
||||||
|
@ -878,7 +878,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
|
||||||
Out << ']';
|
Out << ']';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const ConstantDataArray *CA = dyn_cast<ConstantDataArray>(CV)) {
|
if (const ConstantDataArray *CA = dyn_cast<ConstantDataArray>(CV)) {
|
||||||
// As a special case, print the array as a string if it is an array of
|
// As a special case, print the array as a string if it is an array of
|
||||||
// i8 with ConstantInt values.
|
// i8 with ConstantInt values.
|
||||||
|
|
|
@ -434,14 +434,14 @@ Instruction *Instruction::clone() const {
|
||||||
New->SubclassOptionalData = SubclassOptionalData;
|
New->SubclassOptionalData = SubclassOptionalData;
|
||||||
if (!hasMetadata())
|
if (!hasMetadata())
|
||||||
return New;
|
return New;
|
||||||
|
|
||||||
// Otherwise, enumerate and copy over metadata from the old instruction to the
|
// Otherwise, enumerate and copy over metadata from the old instruction to the
|
||||||
// new one.
|
// new one.
|
||||||
SmallVector<std::pair<unsigned, MDNode*>, 4> TheMDs;
|
SmallVector<std::pair<unsigned, MDNode*>, 4> TheMDs;
|
||||||
getAllMetadataOtherThanDebugLoc(TheMDs);
|
getAllMetadataOtherThanDebugLoc(TheMDs);
|
||||||
for (unsigned i = 0, e = TheMDs.size(); i != e; ++i)
|
for (unsigned i = 0, e = TheMDs.size(); i != e; ++i)
|
||||||
New->setMetadata(TheMDs[i].first, TheMDs[i].second);
|
New->setMetadata(TheMDs[i].first, TheMDs[i].second);
|
||||||
|
|
||||||
New->setDebugLoc(getDebugLoc());
|
New->setDebugLoc(getDebugLoc());
|
||||||
return New;
|
return New;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue