X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FInstruction.cpp;h=c1d638775755ddad2cb79169273d83e63cde8480;hb=4e4c3408a5a1cc72b739a4b448329a281c379c55;hp=879c073dffd01364e92fabfb52cd73ccd500826a;hpb=ab21db79ef1d2530880ad11f21f0b87ffca02dd4;p=oota-llvm.git diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 879c073dffd..c1d63877575 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -11,18 +11,16 @@ // //===----------------------------------------------------------------------===// -#include "LLVMContextImpl.h" +#include "llvm/Instruction.h" #include "llvm/Type.h" #include "llvm/Instructions.h" -#include "llvm/Function.h" #include "llvm/Constants.h" -#include "llvm/GlobalVariable.h" #include "llvm/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; -Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, +Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, Instruction *InsertBefore) : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { // Make sure that we get added to a basicblock @@ -36,7 +34,7 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, } } -Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, +Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { // Make sure that we get added to a basicblock @@ -51,10 +49,8 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, // Out of line virtual method, so the vtable, etc has a home. Instruction::~Instruction() { assert(Parent == 0 && "Instruction still linked in the program!"); - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsDeleted(this); - } + if (hasMetadataHashEntry()) + clearMetadataHashEntries(); } @@ -105,7 +101,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Switch: return "switch"; case IndirectBr: return "indirectbr"; case Invoke: return "invoke"; - case Unwind: return "unwind"; + case Resume: return "resume"; case Unreachable: return "unreachable"; // Standard binary operators... @@ -131,6 +127,9 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Alloca: return "alloca"; case Load: return "load"; case Store: return "store"; + case AtomicCmpXchg: return "cmpxchg"; + case AtomicRMW: return "atomicrmw"; + case Fence: return "fence"; case GetElementPtr: return "getelementptr"; // Convert instructions... @@ -162,11 +161,10 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case ShuffleVector: return "shufflevector"; case ExtractValue: return "extractvalue"; case InsertValue: return "insertvalue"; + case LandingPad: return "landingpad"; default: return " "; } - - return 0; } /// isIdenticalTo - Return true if the specified instruction is exactly @@ -195,38 +193,47 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { // Check special state that is a part of some instructions. if (const LoadInst *LI = dyn_cast(this)) return LI->isVolatile() == cast(I)->isVolatile() && - LI->getAlignment() == cast(I)->getAlignment(); + LI->getAlignment() == cast(I)->getAlignment() && + LI->getOrdering() == cast(I)->getOrdering() && + LI->getSynchScope() == cast(I)->getSynchScope(); if (const StoreInst *SI = dyn_cast(this)) return SI->isVolatile() == cast(I)->isVolatile() && - SI->getAlignment() == cast(I)->getAlignment(); + SI->getAlignment() == cast(I)->getAlignment() && + SI->getOrdering() == cast(I)->getOrdering() && + SI->getSynchScope() == cast(I)->getSynchScope(); if (const CmpInst *CI = dyn_cast(this)) return CI->getPredicate() == cast(I)->getPredicate(); if (const CallInst *CI = dyn_cast(this)) return CI->isTailCall() == cast(I)->isTailCall() && CI->getCallingConv() == cast(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast(I)->getAttributes().getRawPointer(); + CI->getAttributes() == cast(I)->getAttributes(); if (const InvokeInst *CI = dyn_cast(this)) return CI->getCallingConv() == cast(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast(I)->getAttributes().getRawPointer(); - if (const InsertValueInst *IVI = dyn_cast(this)) { - if (IVI->getNumIndices() != cast(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = IVI->getNumIndices(); i != e; ++i) - if (IVI->idx_begin()[i] != cast(I)->idx_begin()[i]) - return false; - return true; - } - if (const ExtractValueInst *EVI = dyn_cast(this)) { - if (EVI->getNumIndices() != cast(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = EVI->getNumIndices(); i != e; ++i) - if (EVI->idx_begin()[i] != cast(I)->idx_begin()[i]) + CI->getAttributes() == cast(I)->getAttributes(); + if (const InsertValueInst *IVI = dyn_cast(this)) + return IVI->getIndices() == cast(I)->getIndices(); + if (const ExtractValueInst *EVI = dyn_cast(this)) + return EVI->getIndices() == cast(I)->getIndices(); + if (const FenceInst *FI = dyn_cast(this)) + return FI->getOrdering() == cast(FI)->getOrdering() && + FI->getSynchScope() == cast(FI)->getSynchScope(); + if (const AtomicCmpXchgInst *CXI = dyn_cast(this)) + return CXI->isVolatile() == cast(I)->isVolatile() && + CXI->getOrdering() == cast(I)->getOrdering() && + CXI->getSynchScope() == cast(I)->getSynchScope(); + if (const AtomicRMWInst *RMWI = dyn_cast(this)) + return RMWI->getOperation() == cast(I)->getOperation() && + RMWI->isVolatile() == cast(I)->isVolatile() && + RMWI->getOrdering() == cast(I)->getOrdering() && + RMWI->getSynchScope() == cast(I)->getSynchScope(); + if (const PHINode *thisPHI = dyn_cast(this)) { + const PHINode *otherPHI = cast(I); + for (unsigned i = 0, e = thisPHI->getNumOperands(); i != e; ++i) { + if (thisPHI->getIncomingBlock(i) != otherPHI->getIncomingBlock(i)) return false; + } return true; } - return true; } @@ -248,37 +255,40 @@ bool Instruction::isSameOperationAs(const Instruction *I) const { // Check special state that is a part of some instructions. if (const LoadInst *LI = dyn_cast(this)) return LI->isVolatile() == cast(I)->isVolatile() && - LI->getAlignment() == cast(I)->getAlignment(); + LI->getAlignment() == cast(I)->getAlignment() && + LI->getOrdering() == cast(I)->getOrdering() && + LI->getSynchScope() == cast(I)->getSynchScope(); if (const StoreInst *SI = dyn_cast(this)) return SI->isVolatile() == cast(I)->isVolatile() && - SI->getAlignment() == cast(I)->getAlignment(); + SI->getAlignment() == cast(I)->getAlignment() && + SI->getOrdering() == cast(I)->getOrdering() && + SI->getSynchScope() == cast(I)->getSynchScope(); if (const CmpInst *CI = dyn_cast(this)) return CI->getPredicate() == cast(I)->getPredicate(); if (const CallInst *CI = dyn_cast(this)) return CI->isTailCall() == cast(I)->isTailCall() && CI->getCallingConv() == cast(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast(I)->getAttributes().getRawPointer(); + CI->getAttributes() == cast(I)->getAttributes(); if (const InvokeInst *CI = dyn_cast(this)) return CI->getCallingConv() == cast(I)->getCallingConv() && - CI->getAttributes().getRawPointer() == - cast(I)->getAttributes().getRawPointer(); - if (const InsertValueInst *IVI = dyn_cast(this)) { - if (IVI->getNumIndices() != cast(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = IVI->getNumIndices(); i != e; ++i) - if (IVI->idx_begin()[i] != cast(I)->idx_begin()[i]) - return false; - return true; - } - if (const ExtractValueInst *EVI = dyn_cast(this)) { - if (EVI->getNumIndices() != cast(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = EVI->getNumIndices(); i != e; ++i) - if (EVI->idx_begin()[i] != cast(I)->idx_begin()[i]) - return false; - return true; - } + CI->getAttributes() == + cast(I)->getAttributes(); + if (const InsertValueInst *IVI = dyn_cast(this)) + return IVI->getIndices() == cast(I)->getIndices(); + if (const ExtractValueInst *EVI = dyn_cast(this)) + return EVI->getIndices() == cast(I)->getIndices(); + if (const FenceInst *FI = dyn_cast(this)) + return FI->getOrdering() == cast(I)->getOrdering() && + FI->getSynchScope() == cast(I)->getSynchScope(); + if (const AtomicCmpXchgInst *CXI = dyn_cast(this)) + return CXI->isVolatile() == cast(I)->isVolatile() && + CXI->getOrdering() == cast(I)->getOrdering() && + CXI->getSynchScope() == cast(I)->getSynchScope(); + if (const AtomicRMWInst *RMWI = dyn_cast(this)) + return RMWI->getOperation() == cast(I)->getOperation() && + RMWI->isVolatile() == cast(I)->isVolatile() && + RMWI->getOrdering() == cast(I)->getOrdering() && + RMWI->getSynchScope() == cast(I)->getSynchScope(); return true; } @@ -287,12 +297,13 @@ bool Instruction::isSameOperationAs(const Instruction *I) const { /// specified block. Note that PHI nodes are considered to evaluate their /// operands in the corresponding predecessor block. bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { - for (use_const_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { + for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { // PHI nodes uses values in the corresponding predecessor block. For other // instructions, just check to see whether the parent of the use matches up. - const PHINode *PN = dyn_cast(*UI); + const User *U = *UI; + const PHINode *PN = dyn_cast(U); if (PN == 0) { - if (cast(*UI)->getParent() != BB) + if (cast(U)->getParent() != BB) return true; continue; } @@ -303,32 +314,6 @@ bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { return false; } -// Code here matches isFreeCall from MemoryBuiltins, which is not in VMCore. -static bool isFreeCall(const Value* I) { - const CallInst *CI = dyn_cast(I); - if (!CI) - return false; - - const Module* M = CI->getParent()->getParent()->getParent(); - Function *FreeFunc = M->getFunction("free"); - - if (CI->getOperand(0) != FreeFunc) - return false; - - // Check free prototype. - // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin - // attribute will exist. - const FunctionType *FTy = FreeFunc->getFunctionType(); - if (FTy->getReturnType() != Type::getVoidTy(M->getContext())) - return false; - if (FTy->getNumParams() != 1) - return false; - if (FTy->param_begin()->get() != Type::getInt8PtrTy(M->getContext())) - return false; - - return true; -} - /// mayReadFromMemory - Return true if this instruction may read memory. /// bool Instruction::mayReadFromMemory() const { @@ -336,15 +321,16 @@ bool Instruction::mayReadFromMemory() const { default: return false; case Instruction::VAArg: case Instruction::Load: + case Instruction::Fence: // FIXME: refine definition of mayReadFromMemory + case Instruction::AtomicCmpXchg: + case Instruction::AtomicRMW: return true; case Instruction::Call: - if (isFreeCall(this)) - return true; return !cast(this)->doesNotAccessMemory(); case Instruction::Invoke: return !cast(this)->doesNotAccessMemory(); case Instruction::Store: - return cast(this)->isVolatile(); + return !cast(this)->isUnordered(); } } @@ -353,17 +339,18 @@ bool Instruction::mayReadFromMemory() const { bool Instruction::mayWriteToMemory() const { switch (getOpcode()) { default: return false; + case Instruction::Fence: // FIXME: refine definition of mayWriteToMemory case Instruction::Store: case Instruction::VAArg: + case Instruction::AtomicCmpXchg: + case Instruction::AtomicRMW: return true; case Instruction::Call: - if (isFreeCall(this)) - return true; return !cast(this)->onlyReadsMemory(); case Instruction::Invoke: return !cast(this)->onlyReadsMemory(); case Instruction::Load: - return cast(this)->isVolatile(); + return !cast(this)->isUnordered(); } } @@ -372,7 +359,7 @@ bool Instruction::mayWriteToMemory() const { bool Instruction::mayThrow() const { if (const CallInst *CI = dyn_cast(this)) return !CI->doesNotThrow(); - return false; + return isa(this); } /// isAssociative - Return true if the instruction is associative: @@ -381,7 +368,7 @@ bool Instruction::mayThrow() const { /// /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. /// -bool Instruction::isAssociative(unsigned Opcode, const Type *Ty) { +bool Instruction::isAssociative(unsigned Opcode) { return Opcode == And || Opcode == Or || Opcode == Xor || Opcode == Add || Opcode == Mul; } @@ -408,95 +395,19 @@ bool Instruction::isCommutative(unsigned op) { } } -// Code here matches isMalloc from MemoryBuiltins, which is not in VMCore. -static bool isMalloc(const Value* I) { - const CallInst *CI = dyn_cast(I); - if (!CI) { - const BitCastInst *BCI = dyn_cast(I); - if (!BCI) return false; - - CI = dyn_cast(BCI->getOperand(0)); - } - - if (!CI) return false; - - const Module* M = CI->getParent()->getParent()->getParent(); - Constant *MallocFunc = M->getFunction("malloc"); - - if (CI->getOperand(0) != MallocFunc) - return false; - - // Check malloc prototype. - // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin - // attribute will exist. - const FunctionType *FTy = cast(MallocFunc)->getFunctionType(); - if (FTy->getNumParams() != 1) - return false; - if (IntegerType *ITy = dyn_cast(FTy->param_begin()->get())) { - if (ITy->getBitWidth() != 32 && ITy->getBitWidth() != 64) - return false; - return true; - } - - return false; -} - -bool Instruction::isSafeToSpeculativelyExecute() const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (Constant *C = dyn_cast(getOperand(i))) - if (C->canTrap()) - return false; - - switch (getOpcode()) { - default: - return true; - case UDiv: - case URem: { - // x / y is undefined if y == 0, but calcuations like x / 3 are safe. - ConstantInt *Op = dyn_cast(getOperand(1)); - return Op && !Op->isNullValue(); - } - case SDiv: - case SRem: { - // x / y is undefined if y == 0, and might be undefined if y == -1, - // but calcuations like x / 3 are safe. - ConstantInt *Op = dyn_cast(getOperand(1)); - return Op && !Op->isNullValue() && !Op->isAllOnesValue(); - } - case Load: { - if (cast(this)->isVolatile()) - return false; - if (isa(getOperand(0)) || isMalloc(getOperand(0))) - return true; - if (GlobalVariable *GV = dyn_cast(getOperand(0))) - return !GV->hasExternalWeakLinkage(); - // FIXME: Handle cases involving GEPs. We have to be careful because - // a load of a out-of-bounds GEP has undefined behavior. - return false; - } - case Call: - return false; // The called function could have undefined behavior or - // side-effects. - // FIXME: We should special-case some intrinsics (bswap, - // overflow-checking arithmetic, etc.) - case VAArg: - case Alloca: - case Invoke: - case PHI: - case Store: - case Ret: - case Br: - case Switch: - case Unwind: - case Unreachable: - return false; // Misc instructions which have effects - } -} - Instruction *Instruction::clone() const { Instruction *New = clone_impl(); New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - getContext().pImpl->TheMetadata.ValueIsCloned(this, New); + if (!hasMetadata()) + return New; + + // Otherwise, enumerate and copy over metadata from the old instruction to the + // new one. + SmallVector, 4> TheMDs; + getAllMetadataOtherThanDebugLoc(TheMDs); + for (unsigned i = 0, e = TheMDs.size(); i != e; ++i) + New->setMetadata(TheMDs[i].first, TheMDs[i].second); + + New->setDebugLoc(getDebugLoc()); return New; }