namespace llvm {
+class LLVMContext;
+
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
// Out of line virtual method, so the vtable, etc has a home.
~Instruction();
- /// mayWriteToMemory - Return true if this instruction may modify memory.
- ///
- bool mayWriteToMemory() const;
-
- /// mayReadFromMemory - Return true if this instruction may read memory.
- ///
- bool mayReadFromMemory() const;
-
/// clone() - Create a copy of 'this' instruction that is identical in all
/// ways except the following:
/// * The instruction has no parent
/// * The instruction has no name
///
- virtual Instruction *clone() const = 0;
+ virtual Instruction *clone(LLVMContext &Context) const = 0;
/// isIdenticalTo - Return true if the specified instruction is exactly
/// identical to the current one. This means that all operands match and any
return getOpcode() == Shl || getOpcode() == LShr;
}
- /// isLogicalShift - Return true if this is a logical shift left or a logical
- /// shift right.
+ /// isArithmeticShift - Return true if this is an arithmetic shift right.
inline bool isArithmeticShift() const {
return getOpcode() == AShr;
}
bool isCommutative() const { return isCommutative(getOpcode()); }
static bool isCommutative(unsigned op);
- /// isTrapping - Return true if the instruction may trap.
+ /// mayWriteToMemory - Return true if this instruction may modify memory.
+ ///
+ bool mayWriteToMemory() const;
+
+ /// mayReadFromMemory - Return true if this instruction may read memory.
+ ///
+ bool mayReadFromMemory() const;
+
+ /// mayThrow - Return true if this instruction may throw an exception.
+ ///
+ bool mayThrow() const;
+
+ /// mayHaveSideEffects - Return true if the instruction may have side effects.
///
- bool isTrapping() const {
- return isTrapping(getOpcode());
+ /// Note that this does not consider malloc and alloca to have side
+ /// effects because the newly allocated memory is completely invisible to
+ /// instructions which don't used the returned value. For cases where this
+ /// matters, isSafeToSpeculativelyExecute may be more appropriate.
+ bool mayHaveSideEffects() const {
+ return mayWriteToMemory() || mayThrow();
}
- static bool isTrapping(unsigned op);
+
+ /// isSafeToSpeculativelyExecute - Return true if the instruction does not
+ /// have any effects besides calculating the result and does not have
+ /// undefined behavior.
+ ///
+ /// This method never returns true for an instruction that returns true for
+ /// mayHaveSideEffects; however, this method also does some other checks in
+ /// addition. It checks for undefined behavior, like dividing by zero or
+ /// loading from an invalid pointer (but not for undefined results, like a
+ /// shift with a shift amount larger than the width of the result). It checks
+ /// for malloc and alloca because speculatively executing them might cause a
+ /// memory leak. It also returns false for instructions related to control
+ /// flow, specifically terminators and PHI nodes.
+ ///
+ /// This method only looks at the instruction itself and its operands, so if
+ /// this method returns true, it is safe to move the instruction as long as
+ /// the correct dominance relationships for the operands and users hold.
+ /// However, this method can return true for instructions that read memory;
+ /// for such instructions, moving them may change the resulting value.
+ bool isSafeToSpeculativelyExecute() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *) { return true; }