/// SubclassData field in Value to store whether or not the load is volatile.
///
class LoadInst : public UnaryInstruction {
+
LoadInst(const LoadInst &LI)
: UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) {
setVolatile(LI.isVolatile());
+ setAlignment(LI.getAlignment());
#ifndef NDEBUG
AssertOK();
public:
LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore);
LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd);
- LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false,
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false,
+ Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align,
Instruction *InsertBefore = 0);
LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
BasicBlock *InsertAtEnd);
LoadInst(Value *Ptr, const char *Name, Instruction *InsertBefore);
LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAtEnd);
- explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false,
+ explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false,
Instruction *InsertBefore = 0);
LoadInst(Value *Ptr, const char *Name, bool isVolatile,
BasicBlock *InsertAtEnd);
/// isVolatile - Return true if this is a load from a volatile memory
/// location.
///
- bool isVolatile() const { return SubclassData; }
+ bool isVolatile() const { return SubclassData & 1; }
/// setVolatile - Specify whether this is a volatile load or not.
///
- void setVolatile(bool V) { SubclassData = V; }
+ void setVolatile(bool V) {
+ SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0);
+ }
virtual LoadInst *clone() const;
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << (SubclassData>>1)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
Value *getPointerOperand() { return getOperand(0); }
const Value *getPointerOperand() const { return getOperand(0); }
static unsigned getPointerOperandIndex() { return 0U; }
///
class StoreInst : public Instruction {
Use Ops[2];
+
StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, Ops, 2) {
Ops[0].init(SI.Ops[0], this);
Ops[1].init(SI.Ops[1], this);
setVolatile(SI.isVolatile());
+ setAlignment(SI.getAlignment());
+
#ifndef NDEBUG
AssertOK();
#endif
StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
Instruction *InsertBefore = 0);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, Instruction *InsertBefore = 0);
StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
/// isVolatile - Return true if this is a load from a volatile memory
/// location.
///
- bool isVolatile() const { return SubclassData; }
+ bool isVolatile() const { return SubclassData & 1; }
/// setVolatile - Specify whether this is a volatile load or not.
///
- void setVolatile(bool V) { SubclassData = V; }
+ void setVolatile(bool V) {
+ SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0);
+ }
/// Transparently provide more efficient getOperand methods.
Value *getOperand(unsigned i) const {
}
unsigned getNumOperands() const { return 2; }
-
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << (SubclassData>>1)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
virtual StoreInst *clone() const;
Value *getPointerOperand() { return getOperand(1); }
/// zeros. If so, the result pointer and the first operand have the same
/// value, just potentially different types.
bool hasAllZeroIndices() const;
+
+ /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+ /// constant integers. If so, the result pointer and the first operand have
+ /// a constant offset between them.
+ bool hasAllConstantIndices() const;
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GetElementPtrInst *) { return true; }