//===-- Instruction.cpp - Implement the Instruction class -----------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the Instruction class for the VMCore library.
//
//===----------------------------------------------------------------------===//
-#include "llvm/Function.h"
-#include "llvm/SymbolTable.h"
#include "llvm/Type.h"
-#include "Support/LeakDetector.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h" // FIXME: remove
+#include "llvm/Function.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/LeakDetector.h"
using namespace llvm;
-Instruction::Instruction(const Type *ty, unsigned it, const std::string &Name,
+Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction *InsertBefore)
- : User(ty, Value::InstructionVal, Name) {
- Parent = 0;
- iType = it;
-
+ : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) {
// Make sure that we get added to a basicblock
LeakDetector::addGarbageObject(this);
}
}
+Instruction::Instruction(const 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
+ LeakDetector::addGarbageObject(this);
+
+ // append this instruction into the basic block
+ assert(InsertAtEnd && "Basic block to append to may not be NULL!");
+ InsertAtEnd->getInstList().push_back(this);
+}
+
+
+// Out of line virtual method, so the vtable, etc has a home.
+Instruction::~Instruction() {
+ assert(Parent == 0 && "Instruction still linked in the program!");
+}
+
+
void Instruction::setParent(BasicBlock *P) {
- if (getParent())
- LeakDetector::addGarbageObject(this);
+ if (getParent()) {
+ if (!P) LeakDetector::addGarbageObject(this);
+ } else {
+ if (P) LeakDetector::removeGarbageObject(this);
+ }
Parent = P;
+}
+
+void Instruction::removeFromParent() {
+ getParent()->getInstList().remove(this);
+}
- if (getParent())
- LeakDetector::removeGarbageObject(this);
+void Instruction::eraseFromParent() {
+ getParent()->getInstList().erase(this);
}
-// Specialize setName to take care of symbol table majik
-void Instruction::setName(const std::string &name, SymbolTable *ST) {
- BasicBlock *P = 0; Function *PP = 0;
- assert((ST == 0 || !getParent() || !getParent()->getParent() ||
- ST == &getParent()->getParent()->getSymbolTable()) &&
- "Invalid symtab argument!");
- if ((P = getParent()) && (PP = P->getParent()) && hasName())
- PP->getSymbolTable().remove(this);
- Value::setName(name);
- if (PP && hasName()) PP->getSymbolTable().insert(this);
+/// moveBefore - Unlink this instruction from its current basic block and
+/// insert it into the basic block that MovePos lives in, right before
+/// MovePos.
+void Instruction::moveBefore(Instruction *MovePos) {
+ MovePos->getParent()->getInstList().splice(MovePos,getParent()->getInstList(),
+ this);
}
case Switch: return "switch";
case Invoke: return "invoke";
case Unwind: return "unwind";
-
+ case Unreachable: return "unreachable";
+
// Standard binary operators...
case Add: return "add";
case Sub: return "sub";
case Mul: return "mul";
- case Div: return "div";
- case Rem: return "rem";
+ case UDiv: return "udiv";
+ case SDiv: return "sdiv";
+ case FDiv: return "fdiv";
+ case URem: return "urem";
+ case SRem: return "srem";
+ case FRem: return "frem";
// Logical operators...
case And: return "and";
case Or : return "or";
case Xor: return "xor";
- // SetCC operators...
- case SetLE: return "setle";
- case SetGE: return "setge";
- case SetLT: return "setlt";
- case SetGT: return "setgt";
- case SetEQ: return "seteq";
- case SetNE: return "setne";
-
// Memory instructions...
case Malloc: return "malloc";
case Free: return "free";
case Load: return "load";
case Store: return "store";
case GetElementPtr: return "getelementptr";
-
+
+ // Convert instructions...
+ case Trunc: return "trunc";
+ case ZExt: return "zext";
+ case SExt: return "sext";
+ case FPTrunc: return "fptrunc";
+ case FPExt: return "fpext";
+ case FPToUI: return "fptoui";
+ case FPToSI: return "fptosi";
+ case UIToFP: return "uitofp";
+ case SIToFP: return "sitofp";
+ case IntToPtr: return "inttoptr";
+ case PtrToInt: return "ptrtoint";
+ case BitCast: return "bitcast";
+
// Other instructions...
- case PHI: return "phi";
- case Cast: return "cast";
- case Call: return "call";
- case Shl: return "shl";
- case Shr: return "shr";
- case VANext: return "vanext";
- case VAArg: return "vaarg";
+ case ICmp: return "icmp";
+ case FCmp: return "fcmp";
+ case PHI: return "phi";
+ case Select: return "select";
+ case Call: return "call";
+ case Shl: return "shl";
+ case LShr: return "lshr";
+ case AShr: return "ashr";
+ case VAArg: return "va_arg";
+ case ExtractElement: return "extractelement";
+ case InsertElement: return "insertelement";
+ case ShuffleVector: return "shufflevector";
default: return "<Invalid operator> ";
}
-
+
return 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 Instruction::isIdenticalTo(Instruction *I) const {
+ if (getOpcode() != I->getOpcode() ||
+ getNumOperands() != I->getNumOperands() ||
+ getType() != I->getType())
+ return false;
+
+ // We have two instructions of identical opcode and #operands. Check to see
+ // if all operands are the same.
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (getOperand(i) != I->getOperand(i))
+ return false;
+
+ // Check special state that is a part of some instructions.
+ if (const LoadInst *LI = dyn_cast<LoadInst>(this))
+ return LI->isVolatile() == cast<LoadInst>(I)->isVolatile();
+ if (const StoreInst *SI = dyn_cast<StoreInst>(this))
+ return SI->isVolatile() == cast<StoreInst>(I)->isVolatile();
+ if (const CmpInst *CI = dyn_cast<CmpInst>(this))
+ return CI->getPredicate() == cast<CmpInst>(I)->getPredicate();
+ if (const CallInst *CI = dyn_cast<CallInst>(this))
+ return CI->isTailCall() == cast<CallInst>(I)->isTailCall();
+ return true;
+}
+
+// isSameOperationAs
+bool Instruction::isSameOperationAs(Instruction *I) const {
+ if (getOpcode() != I->getOpcode() || getType() != I->getType() ||
+ getNumOperands() != I->getNumOperands())
+ return false;
+
+ // We have two instructions of identical opcode and #operands. Check to see
+ // if all operands are the same type
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (getOperand(i)->getType() != I->getOperand(i)->getType())
+ return false;
+
+ // Check special state that is a part of some instructions.
+ if (const LoadInst *LI = dyn_cast<LoadInst>(this))
+ return LI->isVolatile() == cast<LoadInst>(I)->isVolatile();
+ if (const StoreInst *SI = dyn_cast<StoreInst>(this))
+ return SI->isVolatile() == cast<StoreInst>(I)->isVolatile();
+ if (const CmpInst *CI = dyn_cast<CmpInst>(this))
+ return CI->getPredicate() == cast<CmpInst>(I)->getPredicate();
+ if (const CallInst *CI = dyn_cast<CallInst>(this))
+ return CI->isTailCall() == cast<CallInst>(I)->isTailCall();
+
+ return true;
+}
+
+/// mayWriteToMemory - Return true if this instruction may modify memory.
+///
+bool Instruction::mayWriteToMemory() const {
+ switch (getOpcode()) {
+ default: return false;
+ case Instruction::Free:
+ case Instruction::Invoke:
+ case Instruction::Store:
+ case Instruction::VAArg:
+ return true;
+ case Instruction::Call:
+ if (!isa<IntrinsicInst>(this))
+ return true; // FIXME: workaround gcc bootstrap breakage
+ return !cast<CallInst>(this)->onlyReadsMemory();
+ case Instruction::Load:
+ return cast<LoadInst>(this)->isVolatile();
+ }
+}
/// isAssociative - Return true if the instruction is associative:
///
/// applied to floating point types.
///
bool Instruction::isAssociative(unsigned Opcode, const Type *Ty) {
- if (Opcode == Add || Opcode == Mul ||
- Opcode == And || Opcode == Or || Opcode == Xor) {
- // Floating point operations do not associate!
- return !Ty->isFloatingPoint();
- }
+ if (Opcode == And || Opcode == Or || Opcode == Xor)
+ return true;
+
+ // Add/Mul reassociate unless they are FP or FP vectors.
+ if (Opcode == Add || Opcode == Mul)
+ return !Ty->isFPOrFPVector();
return 0;
}
switch (op) {
case Add:
case Mul:
- case And:
+ case And:
case Or:
case Xor:
- case SetEQ:
- case SetNE:
return true;
default:
return false;
}
}
-/// isRelational - Return true if the instruction is a Set* instruction:
-///
-bool Instruction::isRelational(unsigned op) {
- switch (op) {
- case SetEQ:
- case SetNE:
- case SetLT:
- case SetGT:
- case SetLE:
- case SetGE:
- return true;
- }
- return false;
-}
-
-
-
/// isTrappingInstruction - Return true if the instruction may trap.
///
bool Instruction::isTrapping(unsigned op) {
switch(op) {
- case Div:
- case Rem:
+ case UDiv:
+ case SDiv:
+ case FDiv:
+ case URem:
+ case SRem:
+ case FRem:
case Load:
case Store:
case Call: