X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FInstruction.h;h=924b19554a807a529a84631d57ad43f656c07379;hb=b834a7b73ce0dcf8fbf8d8b0d62f69e4b78059ad;hp=f56b96fe5e9921bdf23a68d0332218f27154cb36;hpb=95c2cc51ebb2a58ccd66a1465d5c8ed89b381bc9;p=oota-llvm.git diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index f56b96fe5e9..924b19554a8 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -20,6 +20,8 @@ namespace llvm { +class LLVMContext; + template class SymbolTableListTraits; @@ -40,25 +42,17 @@ public: // 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 /// extra information (e.g. load is volatile) agree. - bool isIdenticalTo(Instruction *I) const; + bool isIdenticalTo(const Instruction *I) const; /// This function determines if the specified instruction executes the same /// operation as the current one. This means that the opcodes, type, operand @@ -68,7 +62,7 @@ public: /// @returns true if the specified instruction is the same operation as /// the current one. /// @brief Determine if one instruction is the same operation as another. - bool isSameOperationAs(Instruction *I) const; + bool isSameOperationAs(const Instruction *I) const; /// isUsedOutsideOfBlock - Return true if there are any uses of this /// instruction in blocks other than the specified block. Note that PHI nodes @@ -101,6 +95,10 @@ public: /// immediately before the specified instruction. void insertBefore(Instruction *InsertPos); + /// insertAfter - Insert an unlinked instructions into a basic block + /// immediately after the specified instruction. + void insertAfter(Instruction *InsertPos); + /// moveBefore - Unlink this instruction from its current basic block and /// insert it into the basic block that MovePos lives in, right before /// MovePos. @@ -140,8 +138,7 @@ public: 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; } @@ -171,12 +168,47 @@ public: 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 isTrapping() const { - return isTrapping(getOpcode()); + 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. + /// + /// 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; } @@ -223,6 +255,18 @@ public: }; }; +// Instruction* is only 4-byte aligned. +template<> +class PointerLikeTypeTraits { + typedef Instruction* PT; +public: + static inline void *getAsVoidPointer(PT P) { return P; } + static inline PT getFromVoidPointer(void *P) { + return static_cast(P); + } + enum { NumLowBitsAvailable = 2 }; +}; + } // End llvm namespace #endif