1249259Sdim//===-- Instruction.cpp - Implement the Instruction class -----------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file implements the Instruction class for the IR library. 11249259Sdim// 12249259Sdim//===----------------------------------------------------------------------===// 13249259Sdim 14249259Sdim#include "llvm/IR/Instruction.h" 15249259Sdim#include "llvm/IR/Constants.h" 16249259Sdim#include "llvm/IR/Instructions.h" 17249259Sdim#include "llvm/IR/Module.h" 18249259Sdim#include "llvm/IR/Operator.h" 19249259Sdim#include "llvm/IR/Type.h" 20249259Sdim#include "llvm/Support/CallSite.h" 21249259Sdim#include "llvm/Support/LeakDetector.h" 22249259Sdimusing namespace llvm; 23249259Sdim 24249259SdimInstruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, 25249259Sdim Instruction *InsertBefore) 26249259Sdim : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { 27249259Sdim // Make sure that we get added to a basicblock 28249259Sdim LeakDetector::addGarbageObject(this); 29249259Sdim 30249259Sdim // If requested, insert this instruction into a basic block... 31249259Sdim if (InsertBefore) { 32249259Sdim assert(InsertBefore->getParent() && 33249259Sdim "Instruction to insert before is not in a basic block!"); 34249259Sdim InsertBefore->getParent()->getInstList().insert(InsertBefore, this); 35249259Sdim } 36249259Sdim} 37249259Sdim 38249259SdimInstruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, 39249259Sdim BasicBlock *InsertAtEnd) 40249259Sdim : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { 41249259Sdim // Make sure that we get added to a basicblock 42249259Sdim LeakDetector::addGarbageObject(this); 43249259Sdim 44249259Sdim // append this instruction into the basic block 45249259Sdim assert(InsertAtEnd && "Basic block to append to may not be NULL!"); 46249259Sdim InsertAtEnd->getInstList().push_back(this); 47249259Sdim} 48249259Sdim 49249259Sdim 50249259Sdim// Out of line virtual method, so the vtable, etc has a home. 51249259SdimInstruction::~Instruction() { 52249259Sdim assert(Parent == 0 && "Instruction still linked in the program!"); 53249259Sdim if (hasMetadataHashEntry()) 54249259Sdim clearMetadataHashEntries(); 55249259Sdim} 56249259Sdim 57249259Sdim 58249259Sdimvoid Instruction::setParent(BasicBlock *P) { 59249259Sdim if (getParent()) { 60249259Sdim if (!P) LeakDetector::addGarbageObject(this); 61249259Sdim } else { 62249259Sdim if (P) LeakDetector::removeGarbageObject(this); 63249259Sdim } 64249259Sdim 65249259Sdim Parent = P; 66249259Sdim} 67249259Sdim 68249259Sdimvoid Instruction::removeFromParent() { 69249259Sdim getParent()->getInstList().remove(this); 70249259Sdim} 71249259Sdim 72249259Sdimvoid Instruction::eraseFromParent() { 73249259Sdim getParent()->getInstList().erase(this); 74249259Sdim} 75249259Sdim 76249259Sdim/// insertBefore - Insert an unlinked instructions into a basic block 77249259Sdim/// immediately before the specified instruction. 78249259Sdimvoid Instruction::insertBefore(Instruction *InsertPos) { 79249259Sdim InsertPos->getParent()->getInstList().insert(InsertPos, this); 80249259Sdim} 81249259Sdim 82249259Sdim/// insertAfter - Insert an unlinked instructions into a basic block 83249259Sdim/// immediately after the specified instruction. 84249259Sdimvoid Instruction::insertAfter(Instruction *InsertPos) { 85249259Sdim InsertPos->getParent()->getInstList().insertAfter(InsertPos, this); 86249259Sdim} 87249259Sdim 88249259Sdim/// moveBefore - Unlink this instruction from its current basic block and 89249259Sdim/// insert it into the basic block that MovePos lives in, right before 90249259Sdim/// MovePos. 91249259Sdimvoid Instruction::moveBefore(Instruction *MovePos) { 92249259Sdim MovePos->getParent()->getInstList().splice(MovePos,getParent()->getInstList(), 93249259Sdim this); 94249259Sdim} 95249259Sdim 96249259Sdim/// Set or clear the unsafe-algebra flag on this instruction, which must be an 97249259Sdim/// operator which supports this flag. See LangRef.html for the meaning of this 98249259Sdim/// flag. 99249259Sdimvoid Instruction::setHasUnsafeAlgebra(bool B) { 100249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 101249259Sdim cast<FPMathOperator>(this)->setHasUnsafeAlgebra(B); 102249259Sdim} 103249259Sdim 104249259Sdim/// Set or clear the NoNaNs flag on this instruction, which must be an operator 105249259Sdim/// which supports this flag. See LangRef.html for the meaning of this flag. 106249259Sdimvoid Instruction::setHasNoNaNs(bool B) { 107249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 108249259Sdim cast<FPMathOperator>(this)->setHasNoNaNs(B); 109249259Sdim} 110249259Sdim 111249259Sdim/// Set or clear the no-infs flag on this instruction, which must be an operator 112249259Sdim/// which supports this flag. See LangRef.html for the meaning of this flag. 113249259Sdimvoid Instruction::setHasNoInfs(bool B) { 114249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 115249259Sdim cast<FPMathOperator>(this)->setHasNoInfs(B); 116249259Sdim} 117249259Sdim 118249259Sdim/// Set or clear the no-signed-zeros flag on this instruction, which must be an 119249259Sdim/// operator which supports this flag. See LangRef.html for the meaning of this 120249259Sdim/// flag. 121249259Sdimvoid Instruction::setHasNoSignedZeros(bool B) { 122249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 123249259Sdim cast<FPMathOperator>(this)->setHasNoSignedZeros(B); 124249259Sdim} 125249259Sdim 126249259Sdim/// Set or clear the allow-reciprocal flag on this instruction, which must be an 127249259Sdim/// operator which supports this flag. See LangRef.html for the meaning of this 128249259Sdim/// flag. 129249259Sdimvoid Instruction::setHasAllowReciprocal(bool B) { 130249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 131249259Sdim cast<FPMathOperator>(this)->setHasAllowReciprocal(B); 132249259Sdim} 133249259Sdim 134249259Sdim/// Convenience function for setting all the fast-math flags on this 135249259Sdim/// instruction, which must be an operator which supports these flags. See 136249259Sdim/// LangRef.html for the meaning of these flats. 137249259Sdimvoid Instruction::setFastMathFlags(FastMathFlags FMF) { 138249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 139249259Sdim cast<FPMathOperator>(this)->setFastMathFlags(FMF); 140249259Sdim} 141249259Sdim 142249259Sdim/// Determine whether the unsafe-algebra flag is set. 143249259Sdimbool Instruction::hasUnsafeAlgebra() const { 144249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 145249259Sdim return cast<FPMathOperator>(this)->hasUnsafeAlgebra(); 146249259Sdim} 147249259Sdim 148249259Sdim/// Determine whether the no-NaNs flag is set. 149249259Sdimbool Instruction::hasNoNaNs() const { 150249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 151249259Sdim return cast<FPMathOperator>(this)->hasNoNaNs(); 152249259Sdim} 153249259Sdim 154249259Sdim/// Determine whether the no-infs flag is set. 155249259Sdimbool Instruction::hasNoInfs() const { 156249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 157249259Sdim return cast<FPMathOperator>(this)->hasNoInfs(); 158249259Sdim} 159249259Sdim 160249259Sdim/// Determine whether the no-signed-zeros flag is set. 161249259Sdimbool Instruction::hasNoSignedZeros() const { 162249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 163249259Sdim return cast<FPMathOperator>(this)->hasNoSignedZeros(); 164249259Sdim} 165249259Sdim 166249259Sdim/// Determine whether the allow-reciprocal flag is set. 167249259Sdimbool Instruction::hasAllowReciprocal() const { 168249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 169249259Sdim return cast<FPMathOperator>(this)->hasAllowReciprocal(); 170249259Sdim} 171249259Sdim 172249259Sdim/// Convenience function for getting all the fast-math flags, which must be an 173249259Sdim/// operator which supports these flags. See LangRef.html for the meaning of 174249259Sdim/// these flats. 175249259SdimFastMathFlags Instruction::getFastMathFlags() const { 176249259Sdim assert(isa<FPMathOperator>(this) && "setting fast-math flag on invalid op"); 177249259Sdim return cast<FPMathOperator>(this)->getFastMathFlags(); 178249259Sdim} 179249259Sdim 180249259Sdim/// Copy I's fast-math flags 181249259Sdimvoid Instruction::copyFastMathFlags(const Instruction *I) { 182249259Sdim setFastMathFlags(I->getFastMathFlags()); 183249259Sdim} 184249259Sdim 185249259Sdim 186249259Sdimconst char *Instruction::getOpcodeName(unsigned OpCode) { 187249259Sdim switch (OpCode) { 188249259Sdim // Terminators 189249259Sdim case Ret: return "ret"; 190249259Sdim case Br: return "br"; 191249259Sdim case Switch: return "switch"; 192249259Sdim case IndirectBr: return "indirectbr"; 193249259Sdim case Invoke: return "invoke"; 194249259Sdim case Resume: return "resume"; 195249259Sdim case Unreachable: return "unreachable"; 196249259Sdim 197249259Sdim // Standard binary operators... 198249259Sdim case Add: return "add"; 199249259Sdim case FAdd: return "fadd"; 200249259Sdim case Sub: return "sub"; 201249259Sdim case FSub: return "fsub"; 202249259Sdim case Mul: return "mul"; 203249259Sdim case FMul: return "fmul"; 204249259Sdim case UDiv: return "udiv"; 205249259Sdim case SDiv: return "sdiv"; 206249259Sdim case FDiv: return "fdiv"; 207249259Sdim case URem: return "urem"; 208249259Sdim case SRem: return "srem"; 209249259Sdim case FRem: return "frem"; 210249259Sdim 211249259Sdim // Logical operators... 212249259Sdim case And: return "and"; 213249259Sdim case Or : return "or"; 214249259Sdim case Xor: return "xor"; 215249259Sdim 216249259Sdim // Memory instructions... 217249259Sdim case Alloca: return "alloca"; 218249259Sdim case Load: return "load"; 219249259Sdim case Store: return "store"; 220249259Sdim case AtomicCmpXchg: return "cmpxchg"; 221249259Sdim case AtomicRMW: return "atomicrmw"; 222249259Sdim case Fence: return "fence"; 223249259Sdim case GetElementPtr: return "getelementptr"; 224249259Sdim 225249259Sdim // Convert instructions... 226263509Sdim case Trunc: return "trunc"; 227263509Sdim case ZExt: return "zext"; 228263509Sdim case SExt: return "sext"; 229263509Sdim case FPTrunc: return "fptrunc"; 230263509Sdim case FPExt: return "fpext"; 231263509Sdim case FPToUI: return "fptoui"; 232263509Sdim case FPToSI: return "fptosi"; 233263509Sdim case UIToFP: return "uitofp"; 234263509Sdim case SIToFP: return "sitofp"; 235263509Sdim case IntToPtr: return "inttoptr"; 236263509Sdim case PtrToInt: return "ptrtoint"; 237263509Sdim case BitCast: return "bitcast"; 238263509Sdim case AddrSpaceCast: return "addrspacecast"; 239249259Sdim 240249259Sdim // Other instructions... 241249259Sdim case ICmp: return "icmp"; 242249259Sdim case FCmp: return "fcmp"; 243249259Sdim case PHI: return "phi"; 244249259Sdim case Select: return "select"; 245249259Sdim case Call: return "call"; 246249259Sdim case Shl: return "shl"; 247249259Sdim case LShr: return "lshr"; 248249259Sdim case AShr: return "ashr"; 249249259Sdim case VAArg: return "va_arg"; 250249259Sdim case ExtractElement: return "extractelement"; 251249259Sdim case InsertElement: return "insertelement"; 252249259Sdim case ShuffleVector: return "shufflevector"; 253249259Sdim case ExtractValue: return "extractvalue"; 254249259Sdim case InsertValue: return "insertvalue"; 255249259Sdim case LandingPad: return "landingpad"; 256249259Sdim 257249259Sdim default: return "<Invalid operator> "; 258249259Sdim } 259249259Sdim} 260249259Sdim 261249259Sdim/// isIdenticalTo - Return true if the specified instruction is exactly 262249259Sdim/// identical to the current one. This means that all operands match and any 263249259Sdim/// extra information (e.g. load is volatile) agree. 264249259Sdimbool Instruction::isIdenticalTo(const Instruction *I) const { 265249259Sdim return isIdenticalToWhenDefined(I) && 266249259Sdim SubclassOptionalData == I->SubclassOptionalData; 267249259Sdim} 268249259Sdim 269249259Sdim/// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it 270249259Sdim/// ignores the SubclassOptionalData flags, which specify conditions 271249259Sdim/// under which the instruction's result is undefined. 272249259Sdimbool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { 273249259Sdim if (getOpcode() != I->getOpcode() || 274249259Sdim getNumOperands() != I->getNumOperands() || 275249259Sdim getType() != I->getType()) 276249259Sdim return false; 277249259Sdim 278249259Sdim // We have two instructions of identical opcode and #operands. Check to see 279249259Sdim // if all operands are the same. 280249259Sdim for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 281249259Sdim if (getOperand(i) != I->getOperand(i)) 282249259Sdim return false; 283249259Sdim 284249259Sdim // Check special state that is a part of some instructions. 285249259Sdim if (const LoadInst *LI = dyn_cast<LoadInst>(this)) 286249259Sdim return LI->isVolatile() == cast<LoadInst>(I)->isVolatile() && 287249259Sdim LI->getAlignment() == cast<LoadInst>(I)->getAlignment() && 288249259Sdim LI->getOrdering() == cast<LoadInst>(I)->getOrdering() && 289249259Sdim LI->getSynchScope() == cast<LoadInst>(I)->getSynchScope(); 290249259Sdim if (const StoreInst *SI = dyn_cast<StoreInst>(this)) 291249259Sdim return SI->isVolatile() == cast<StoreInst>(I)->isVolatile() && 292249259Sdim SI->getAlignment() == cast<StoreInst>(I)->getAlignment() && 293249259Sdim SI->getOrdering() == cast<StoreInst>(I)->getOrdering() && 294249259Sdim SI->getSynchScope() == cast<StoreInst>(I)->getSynchScope(); 295249259Sdim if (const CmpInst *CI = dyn_cast<CmpInst>(this)) 296249259Sdim return CI->getPredicate() == cast<CmpInst>(I)->getPredicate(); 297249259Sdim if (const CallInst *CI = dyn_cast<CallInst>(this)) 298249259Sdim return CI->isTailCall() == cast<CallInst>(I)->isTailCall() && 299249259Sdim CI->getCallingConv() == cast<CallInst>(I)->getCallingConv() && 300249259Sdim CI->getAttributes() == cast<CallInst>(I)->getAttributes(); 301249259Sdim if (const InvokeInst *CI = dyn_cast<InvokeInst>(this)) 302249259Sdim return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && 303249259Sdim CI->getAttributes() == cast<InvokeInst>(I)->getAttributes(); 304249259Sdim if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) 305249259Sdim return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices(); 306249259Sdim if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) 307249259Sdim return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices(); 308249259Sdim if (const FenceInst *FI = dyn_cast<FenceInst>(this)) 309249259Sdim return FI->getOrdering() == cast<FenceInst>(FI)->getOrdering() && 310249259Sdim FI->getSynchScope() == cast<FenceInst>(FI)->getSynchScope(); 311249259Sdim if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(this)) 312249259Sdim return CXI->isVolatile() == cast<AtomicCmpXchgInst>(I)->isVolatile() && 313249259Sdim CXI->getOrdering() == cast<AtomicCmpXchgInst>(I)->getOrdering() && 314249259Sdim CXI->getSynchScope() == cast<AtomicCmpXchgInst>(I)->getSynchScope(); 315249259Sdim if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(this)) 316249259Sdim return RMWI->getOperation() == cast<AtomicRMWInst>(I)->getOperation() && 317249259Sdim RMWI->isVolatile() == cast<AtomicRMWInst>(I)->isVolatile() && 318249259Sdim RMWI->getOrdering() == cast<AtomicRMWInst>(I)->getOrdering() && 319249259Sdim RMWI->getSynchScope() == cast<AtomicRMWInst>(I)->getSynchScope(); 320249259Sdim if (const PHINode *thisPHI = dyn_cast<PHINode>(this)) { 321249259Sdim const PHINode *otherPHI = cast<PHINode>(I); 322249259Sdim for (unsigned i = 0, e = thisPHI->getNumOperands(); i != e; ++i) { 323249259Sdim if (thisPHI->getIncomingBlock(i) != otherPHI->getIncomingBlock(i)) 324249259Sdim return false; 325249259Sdim } 326249259Sdim return true; 327249259Sdim } 328249259Sdim return true; 329249259Sdim} 330249259Sdim 331249259Sdim// isSameOperationAs 332249259Sdim// This should be kept in sync with isEquivalentOperation in 333249259Sdim// lib/Transforms/IPO/MergeFunctions.cpp. 334249259Sdimbool Instruction::isSameOperationAs(const Instruction *I, 335249259Sdim unsigned flags) const { 336249259Sdim bool IgnoreAlignment = flags & CompareIgnoringAlignment; 337249259Sdim bool UseScalarTypes = flags & CompareUsingScalarTypes; 338249259Sdim 339249259Sdim if (getOpcode() != I->getOpcode() || 340249259Sdim getNumOperands() != I->getNumOperands() || 341249259Sdim (UseScalarTypes ? 342249259Sdim getType()->getScalarType() != I->getType()->getScalarType() : 343249259Sdim getType() != I->getType())) 344249259Sdim return false; 345249259Sdim 346249259Sdim // We have two instructions of identical opcode and #operands. Check to see 347249259Sdim // if all operands are the same type 348249259Sdim for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 349249259Sdim if (UseScalarTypes ? 350249259Sdim getOperand(i)->getType()->getScalarType() != 351249259Sdim I->getOperand(i)->getType()->getScalarType() : 352249259Sdim getOperand(i)->getType() != I->getOperand(i)->getType()) 353249259Sdim return false; 354249259Sdim 355249259Sdim // Check special state that is a part of some instructions. 356249259Sdim if (const LoadInst *LI = dyn_cast<LoadInst>(this)) 357249259Sdim return LI->isVolatile() == cast<LoadInst>(I)->isVolatile() && 358249259Sdim (LI->getAlignment() == cast<LoadInst>(I)->getAlignment() || 359249259Sdim IgnoreAlignment) && 360249259Sdim LI->getOrdering() == cast<LoadInst>(I)->getOrdering() && 361249259Sdim LI->getSynchScope() == cast<LoadInst>(I)->getSynchScope(); 362249259Sdim if (const StoreInst *SI = dyn_cast<StoreInst>(this)) 363249259Sdim return SI->isVolatile() == cast<StoreInst>(I)->isVolatile() && 364249259Sdim (SI->getAlignment() == cast<StoreInst>(I)->getAlignment() || 365249259Sdim IgnoreAlignment) && 366249259Sdim SI->getOrdering() == cast<StoreInst>(I)->getOrdering() && 367249259Sdim SI->getSynchScope() == cast<StoreInst>(I)->getSynchScope(); 368249259Sdim if (const CmpInst *CI = dyn_cast<CmpInst>(this)) 369249259Sdim return CI->getPredicate() == cast<CmpInst>(I)->getPredicate(); 370249259Sdim if (const CallInst *CI = dyn_cast<CallInst>(this)) 371249259Sdim return CI->isTailCall() == cast<CallInst>(I)->isTailCall() && 372249259Sdim CI->getCallingConv() == cast<CallInst>(I)->getCallingConv() && 373249259Sdim CI->getAttributes() == cast<CallInst>(I)->getAttributes(); 374249259Sdim if (const InvokeInst *CI = dyn_cast<InvokeInst>(this)) 375249259Sdim return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && 376249259Sdim CI->getAttributes() == 377249259Sdim cast<InvokeInst>(I)->getAttributes(); 378249259Sdim if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) 379249259Sdim return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices(); 380249259Sdim if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) 381249259Sdim return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices(); 382249259Sdim if (const FenceInst *FI = dyn_cast<FenceInst>(this)) 383249259Sdim return FI->getOrdering() == cast<FenceInst>(I)->getOrdering() && 384249259Sdim FI->getSynchScope() == cast<FenceInst>(I)->getSynchScope(); 385249259Sdim if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(this)) 386249259Sdim return CXI->isVolatile() == cast<AtomicCmpXchgInst>(I)->isVolatile() && 387249259Sdim CXI->getOrdering() == cast<AtomicCmpXchgInst>(I)->getOrdering() && 388249259Sdim CXI->getSynchScope() == cast<AtomicCmpXchgInst>(I)->getSynchScope(); 389249259Sdim if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(this)) 390249259Sdim return RMWI->getOperation() == cast<AtomicRMWInst>(I)->getOperation() && 391249259Sdim RMWI->isVolatile() == cast<AtomicRMWInst>(I)->isVolatile() && 392249259Sdim RMWI->getOrdering() == cast<AtomicRMWInst>(I)->getOrdering() && 393249259Sdim RMWI->getSynchScope() == cast<AtomicRMWInst>(I)->getSynchScope(); 394249259Sdim 395249259Sdim return true; 396249259Sdim} 397249259Sdim 398249259Sdim/// isUsedOutsideOfBlock - Return true if there are any uses of I outside of the 399249259Sdim/// specified block. Note that PHI nodes are considered to evaluate their 400249259Sdim/// operands in the corresponding predecessor block. 401249259Sdimbool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { 402249259Sdim for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { 403249259Sdim // PHI nodes uses values in the corresponding predecessor block. For other 404249259Sdim // instructions, just check to see whether the parent of the use matches up. 405249259Sdim const User *U = *UI; 406249259Sdim const PHINode *PN = dyn_cast<PHINode>(U); 407249259Sdim if (PN == 0) { 408249259Sdim if (cast<Instruction>(U)->getParent() != BB) 409249259Sdim return true; 410249259Sdim continue; 411249259Sdim } 412249259Sdim 413249259Sdim if (PN->getIncomingBlock(UI) != BB) 414249259Sdim return true; 415249259Sdim } 416249259Sdim return false; 417249259Sdim} 418249259Sdim 419249259Sdim/// mayReadFromMemory - Return true if this instruction may read memory. 420249259Sdim/// 421249259Sdimbool Instruction::mayReadFromMemory() const { 422249259Sdim switch (getOpcode()) { 423249259Sdim default: return false; 424249259Sdim case Instruction::VAArg: 425249259Sdim case Instruction::Load: 426249259Sdim case Instruction::Fence: // FIXME: refine definition of mayReadFromMemory 427249259Sdim case Instruction::AtomicCmpXchg: 428249259Sdim case Instruction::AtomicRMW: 429249259Sdim return true; 430249259Sdim case Instruction::Call: 431249259Sdim return !cast<CallInst>(this)->doesNotAccessMemory(); 432249259Sdim case Instruction::Invoke: 433249259Sdim return !cast<InvokeInst>(this)->doesNotAccessMemory(); 434249259Sdim case Instruction::Store: 435249259Sdim return !cast<StoreInst>(this)->isUnordered(); 436249259Sdim } 437249259Sdim} 438249259Sdim 439249259Sdim/// mayWriteToMemory - Return true if this instruction may modify memory. 440249259Sdim/// 441249259Sdimbool Instruction::mayWriteToMemory() const { 442249259Sdim switch (getOpcode()) { 443249259Sdim default: return false; 444249259Sdim case Instruction::Fence: // FIXME: refine definition of mayWriteToMemory 445249259Sdim case Instruction::Store: 446249259Sdim case Instruction::VAArg: 447249259Sdim case Instruction::AtomicCmpXchg: 448249259Sdim case Instruction::AtomicRMW: 449249259Sdim return true; 450249259Sdim case Instruction::Call: 451249259Sdim return !cast<CallInst>(this)->onlyReadsMemory(); 452249259Sdim case Instruction::Invoke: 453249259Sdim return !cast<InvokeInst>(this)->onlyReadsMemory(); 454249259Sdim case Instruction::Load: 455249259Sdim return !cast<LoadInst>(this)->isUnordered(); 456249259Sdim } 457249259Sdim} 458249259Sdim 459249259Sdimbool Instruction::mayThrow() const { 460249259Sdim if (const CallInst *CI = dyn_cast<CallInst>(this)) 461249259Sdim return !CI->doesNotThrow(); 462249259Sdim return isa<ResumeInst>(this); 463249259Sdim} 464249259Sdim 465249259Sdimbool Instruction::mayReturn() const { 466249259Sdim if (const CallInst *CI = dyn_cast<CallInst>(this)) 467249259Sdim return !CI->doesNotReturn(); 468249259Sdim return true; 469249259Sdim} 470249259Sdim 471249259Sdim/// isAssociative - Return true if the instruction is associative: 472249259Sdim/// 473249259Sdim/// Associative operators satisfy: x op (y op z) === (x op y) op z 474249259Sdim/// 475249259Sdim/// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. 476249259Sdim/// 477249259Sdimbool Instruction::isAssociative(unsigned Opcode) { 478249259Sdim return Opcode == And || Opcode == Or || Opcode == Xor || 479249259Sdim Opcode == Add || Opcode == Mul; 480249259Sdim} 481249259Sdim 482249259Sdimbool Instruction::isAssociative() const { 483249259Sdim unsigned Opcode = getOpcode(); 484249259Sdim if (isAssociative(Opcode)) 485249259Sdim return true; 486249259Sdim 487249259Sdim switch (Opcode) { 488249259Sdim case FMul: 489249259Sdim case FAdd: 490249259Sdim return cast<FPMathOperator>(this)->hasUnsafeAlgebra(); 491249259Sdim default: 492249259Sdim return false; 493249259Sdim } 494249259Sdim} 495249259Sdim 496249259Sdim/// isCommutative - Return true if the instruction is commutative: 497249259Sdim/// 498249259Sdim/// Commutative operators satisfy: (x op y) === (y op x) 499249259Sdim/// 500249259Sdim/// In LLVM, these are the associative operators, plus SetEQ and SetNE, when 501249259Sdim/// applied to any type. 502249259Sdim/// 503249259Sdimbool Instruction::isCommutative(unsigned op) { 504249259Sdim switch (op) { 505249259Sdim case Add: 506249259Sdim case FAdd: 507249259Sdim case Mul: 508249259Sdim case FMul: 509249259Sdim case And: 510249259Sdim case Or: 511249259Sdim case Xor: 512249259Sdim return true; 513249259Sdim default: 514249259Sdim return false; 515249259Sdim } 516249259Sdim} 517249259Sdim 518249259Sdim/// isIdempotent - Return true if the instruction is idempotent: 519249259Sdim/// 520249259Sdim/// Idempotent operators satisfy: x op x === x 521249259Sdim/// 522249259Sdim/// In LLVM, the And and Or operators are idempotent. 523249259Sdim/// 524249259Sdimbool Instruction::isIdempotent(unsigned Opcode) { 525249259Sdim return Opcode == And || Opcode == Or; 526249259Sdim} 527249259Sdim 528249259Sdim/// isNilpotent - Return true if the instruction is nilpotent: 529249259Sdim/// 530249259Sdim/// Nilpotent operators satisfy: x op x === Id, 531249259Sdim/// 532249259Sdim/// where Id is the identity for the operator, i.e. a constant such that 533249259Sdim/// x op Id === x and Id op x === x for all x. 534249259Sdim/// 535249259Sdim/// In LLVM, the Xor operator is nilpotent. 536249259Sdim/// 537249259Sdimbool Instruction::isNilpotent(unsigned Opcode) { 538249259Sdim return Opcode == Xor; 539249259Sdim} 540249259Sdim 541249259SdimInstruction *Instruction::clone() const { 542249259Sdim Instruction *New = clone_impl(); 543249259Sdim New->SubclassOptionalData = SubclassOptionalData; 544249259Sdim if (!hasMetadata()) 545249259Sdim return New; 546249259Sdim 547249259Sdim // Otherwise, enumerate and copy over metadata from the old instruction to the 548249259Sdim // new one. 549249259Sdim SmallVector<std::pair<unsigned, MDNode*>, 4> TheMDs; 550249259Sdim getAllMetadataOtherThanDebugLoc(TheMDs); 551249259Sdim for (unsigned i = 0, e = TheMDs.size(); i != e; ++i) 552249259Sdim New->setMetadata(TheMDs[i].first, TheMDs[i].second); 553249259Sdim 554249259Sdim New->setDebugLoc(getDebugLoc()); 555249259Sdim return New; 556249259Sdim} 557