llvm-6502/include/llvm/Value.h
Chris Lattner c230978a82 Annotations are evil. This makes Value not derive from Annotable, which makes
all dynamically allocated LLVM values 4 bytes smaller, eliminate some vtables, and
make Value's destructor faster.

This makes Function derive from Annotation now because it is the only core LLVM
class that still has an annotation stuck onto it: MachineFunction.
MachineFunction is obviously horrible and gross (like most other annotations), but
will be the subject of refactorings later in the future.  Besides many fewer
Function objects are dynamically allocated that instructions blocks, constants,
types, etc... :)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11878 91177308-0d34-0410-b5e6-96231b3b80d8
2004-02-26 08:08:38 +00:00

205 lines
6.4 KiB
C++

//===-- llvm/Value.h - Definition of the Value class ------------*- C++ -*-===//
//
// 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 defines the very important Value class. This is subclassed by a
// bunch of other important classes, like Instruction, Function, Type, etc...
//
// This file also defines the Use<> template for users of value.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_VALUE_H
#define LLVM_VALUE_H
#include "llvm/AbstractTypeUser.h"
#include "llvm/Use.h"
#include "Support/Casting.h"
#include <iostream>
namespace llvm {
class Type;
class Constant;
class Argument;
class Instruction;
class BasicBlock;
class GlobalValue;
class Function;
class GlobalVariable;
class SymbolTable;
//===----------------------------------------------------------------------===//
// Value Class
//===----------------------------------------------------------------------===//
/// Value - The base class of all values computed by a program that may be used
/// as operands to other values.
///
struct Value {
enum ValueTy {
TypeVal, // This is an instance of Type
ConstantVal, // This is an instance of Constant
ArgumentVal, // This is an instance of Argument
InstructionVal, // This is an instance of Instruction
BasicBlockVal, // This is an instance of BasicBlock
FunctionVal, // This is an instance of Function
GlobalVariableVal, // This is an instance of GlobalVariable
};
private:
iplist<Use> Uses;
std::string Name;
PATypeHolder Ty;
ValueTy VTy;
void operator=(const Value &); // Do not implement
Value(const Value &); // Do not implement
public:
Value(const Type *Ty, ValueTy vty, const std::string &name = "");
virtual ~Value();
/// dump - Support for debugging, callable in GDB: V->dump()
//
virtual void dump() const;
/// print - Implement operator<< on Value...
///
virtual void print(std::ostream &O) const = 0;
/// All values are typed, get the type of this value.
///
inline const Type *getType() const { return Ty; }
// All values can potentially be named...
inline bool hasName() const { return !Name.empty(); }
inline const std::string &getName() const { return Name; }
virtual void setName(const std::string &name, SymbolTable * = 0) {
Name = name;
}
/// getValueType - Return the immediate subclass of this Value.
///
inline ValueTy getValueType() const { return VTy; }
/// replaceAllUsesWith - Go through the uses list for this definition and make
/// each use point to "V" instead of "this". After this completes, 'this's
/// use list is guaranteed to be empty.
///
void replaceAllUsesWith(Value *V);
// uncheckedReplaceAllUsesWith - Just like replaceAllUsesWith but dangerous.
// Only use when in type resolution situations!
void uncheckedReplaceAllUsesWith(Value *V);
//----------------------------------------------------------------------
// Methods for handling the vector of uses of this Value.
//
typedef UseListIteratorWrapper use_iterator;
typedef UseListConstIteratorWrapper use_const_iterator;
unsigned use_size() const { return Uses.size(); }
bool use_empty() const { return Uses.empty(); }
use_iterator use_begin() { return Uses.begin(); }
use_const_iterator use_begin() const { return Uses.begin(); }
use_iterator use_end() { return Uses.end(); }
use_const_iterator use_end() const { return Uses.end(); }
User *use_back() { return Uses.back().getUser(); }
const User *use_back() const { return Uses.back().getUser(); }
/// hasOneUse - Return true if there is exactly one user of this value. This
/// is specialized because it is a common request and does not require
/// traversing the whole use list.
///
bool hasOneUse() const {
iplist<Use>::const_iterator I = Uses.begin(), E = Uses.end();
if (I == E) return false;
return ++I == E;
}
/// addUse/killUse - These two methods should only be used by the Use class.
///
void addUse(Use &U) { Uses.push_back(&U); }
void killUse(Use &U) { Uses.remove(&U); }
};
inline std::ostream &operator<<(std::ostream &OS, const Value *V) {
if (V == 0)
OS << "<null> value!\n";
else
V->print(OS);
return OS;
}
inline std::ostream &operator<<(std::ostream &OS, const Value &V) {
V.print(OS);
return OS;
}
inline User *UseListIteratorWrapper::operator*() const {
return Super::operator*().getUser();
}
inline const User *UseListConstIteratorWrapper::operator*() const {
return Super::operator*().getUser();
}
Use::Use(Value *v, User *user) : Val(v), U(user) {
if (Val) Val->addUse(*this);
}
Use::Use(const Use &u) : Val(u.Val), U(u.U) {
if (Val) Val->addUse(*this);
}
Use::~Use() {
if (Val) Val->killUse(*this);
}
void Use::set(Value *V) {
if (Val) Val->killUse(*this);
Val = V;
if (V) V->addUse(*this);
}
// isa - Provide some specializations of isa so that we don't have to include
// the subtype header files to test to see if the value is a subclass...
//
template <> inline bool isa_impl<Type, Value>(const Value &Val) {
return Val.getValueType() == Value::TypeVal;
}
template <> inline bool isa_impl<Constant, Value>(const Value &Val) {
return Val.getValueType() == Value::ConstantVal;
}
template <> inline bool isa_impl<Argument, Value>(const Value &Val) {
return Val.getValueType() == Value::ArgumentVal;
}
template <> inline bool isa_impl<Instruction, Value>(const Value &Val) {
return Val.getValueType() == Value::InstructionVal;
}
template <> inline bool isa_impl<BasicBlock, Value>(const Value &Val) {
return Val.getValueType() == Value::BasicBlockVal;
}
template <> inline bool isa_impl<Function, Value>(const Value &Val) {
return Val.getValueType() == Value::FunctionVal;
}
template <> inline bool isa_impl<GlobalVariable, Value>(const Value &Val) {
return Val.getValueType() == Value::GlobalVariableVal;
}
template <> inline bool isa_impl<GlobalValue, Value>(const Value &Val) {
return isa<GlobalVariable>(Val) || isa<Function>(Val);
}
} // End llvm namespace
#endif