LLVM API Documentation
#include <DSNode.h>
Collaboration diagram for llvm::DSNode:
Public Types | |
typedef DSNodeIterator< DSNode > | iterator |
typedef DSNodeIterator< const DSNode > | const_iterator |
typedef std::vector< DSNodeHandle >::iterator | edge_iterator |
typedef std::vector< DSNodeHandle >::const_iterator | const_edge_iterator |
typedef std::vector< GlobalValue * >::const_iterator | globals_iterator |
ShadowNode = 0 | |
AllocaNode = 1 << 0 | |
HeapNode = 1 << 1 | |
GlobalNode = 1 << 2 | |
UnknownNode = 1 << 3 | |
Incomplete = 1 << 4 | |
Modified = 1 << 5 | |
Read = 1 << 6 | |
Array = 1 << 7 | |
DEAD = 1 << 8 | |
Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode | |
enum | NodeTy { ShadowNode = 0, AllocaNode = 1 << 0, HeapNode = 1 << 1, GlobalNode = 1 << 2, UnknownNode = 1 << 3, Incomplete = 1 << 4, Modified = 1 << 5, Read = 1 << 6, Array = 1 << 7, DEAD = 1 << 8, Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode } |
Public Member Functions | |
DSNode (const Type *T, DSGraph *G) | |
DSNode (const DSNode &, DSGraph *G, bool NullLinks=false) | |
~DSNode () | |
iterator | begin () |
iterator | end () |
const_iterator | begin () const |
const_iterator | end () const |
unsigned | getSize () const |
const Type * | getType () const |
bool | isArray () const |
bool | hasNoReferrers () const |
unsigned | getNumReferrers () const |
DSGraph * | getParentGraph () const |
void | setParentGraph (DSGraph *G) |
const TargetData & | getTargetData () const |
DSNode * | getForwardNode () const |
bool | isForwarding () const |
void | stopForwarding () |
bool | hasLink (unsigned Offset) const |
DSNodeHandle & | getLink (unsigned Offset) |
const DSNodeHandle & | getLink (unsigned Offset) const |
unsigned | getNumLinks () const |
edge_iterator | edge_begin () |
edge_iterator | edge_end () |
const_edge_iterator | edge_begin () const |
const_edge_iterator | edge_end () const |
bool | mergeTypeInfo (const Type *Ty, unsigned Offset, bool FoldIfIncompatible=true) |
void | foldNodeCompletely () |
bool | isNodeCompletelyFolded () const |
void | setLink (unsigned Offset, const DSNodeHandle &NH) |
unsigned | getPointerSize () const |
void | addEdgeTo (unsigned Offset, const DSNodeHandle &NH) |
void | mergeWith (const DSNodeHandle &NH, unsigned Offset) |
void | addGlobal (GlobalValue *GV) |
void | removeGlobal (GlobalValue *GV) |
void | mergeGlobals (const std::vector< GlobalValue * > &RHS) |
void | clearGlobals () |
const std::vector< GlobalValue * > & | getGlobalsList () const |
void | addFullGlobalsList (std::vector< GlobalValue * > &List) const |
void | addFullFunctionList (std::vector< Function * > &List) const |
globals_iterator | globals_begin () const |
globals_iterator | globals_end () const |
void | maskNodeTypes (unsigned Mask) |
void | mergeNodeFlags (unsigned RHS) |
unsigned | getNodeFlags () const |
bool | isAllocaNode () const |
bool | isHeapNode () const |
bool | isGlobalNode () const |
bool | isUnknownNode () const |
bool | isModified () const |
bool | isRead () const |
bool | isIncomplete () const |
bool | isComplete () const |
bool | isDeadNode () const |
DSNode * | setAllocaNodeMarker () |
DSNode * | setHeapNodeMarker () |
DSNode * | setGlobalNodeMarker () |
DSNode * | setUnknownNodeMarker () |
DSNode * | setIncompleteMarker () |
DSNode * | setModifiedMarker () |
DSNode * | setReadMarker () |
DSNode * | setArrayMarker () |
void | makeNodeDead () |
void | forwardNode (DSNode *To, unsigned Offset) |
void | print (std::ostream &O, const DSGraph *G) const |
void | dump () const |
void | assertOK () const |
void | dropAllReferences () |
void | remapLinks (hash_map< const DSNode *, DSNodeHandle > &OldNodeMap) |
void | markReachableNodes (hash_set< const DSNode * > &ReachableNodes) const |
Friends | |
struct | ilist_traits< DSNode > |
class | DSNodeHandle |
This class represents an untyped memory object of Size bytes. It keeps track of any pointers that have been stored into the object as well as the different types represented in this object.
Definition at line 33 of file DSNode.h.
typedef std::vector<DSNodeHandle>::const_iterator llvm::DSNode::const_edge_iterator |
typedef DSNodeIterator<const DSNode> llvm::DSNode::const_iterator |
typedef std::vector<DSNodeHandle>::iterator llvm::DSNode::edge_iterator |
typedef std::vector<GlobalValue*>::const_iterator llvm::DSNode::globals_iterator |
globals_iterator/begin/end - Provide iteration methods over the global value leaders set that is merged into this node. Like the getGlobalsList method, these iterators do not return globals that are part of the equivalence classes for globals in this node, but aren't leaders.
typedef DSNodeIterator<DSNode> llvm::DSNode::iterator |
enum llvm::DSNode::NodeTy |
DSNode ctor - Create a node of the specified type, inserting it into the specified graph.
Definition at line 116 of file DataStructure.cpp.
References llvm::DSGraph::addNode(), G, mergeTypeInfo(), NumNodeAllocated, and T.
DSNode "copy ctor" - Copy the specified node, inserting it into the specified graph. If NullLinks is true, then null out all of the links, but keep the same number of them. This can be used for efficiency if the links are just going to be clobbered anyway.
Definition at line 125 of file DataStructure.cpp.
References llvm::DSGraph::addNode(), G, Links, and NumNodeAllocated.
llvm::DSNode::~DSNode | ( | ) | [inline] |
void DSNode::addEdgeTo | ( | unsigned | Offset, | |
const DSNodeHandle & | NH | |||
) |
addEdgeTo - Add an edge from the current node to the specified node. This can cause merging of nodes in the graph.
Definition at line 701 of file DataStructure.cpp.
References getLink(), isNodeCompletelyFolded(), llvm::DSNodeHandle::isNull(), llvm::DSNodeHandle::mergeWith(), and setLink().
Referenced by llvm::DSNodeHandle::addEdgeTo(), and llvm::ReachabilityCloner::getClonedNH().
void DSNode::addFullFunctionList | ( | std::vector< Function * > & | List | ) | const |
addFullFunctionList - Identical to addFullGlobalsList, but only return the functions in the full list.
Definition at line 276 of file DataStructure.cpp.
References E, llvm::EquivalenceClasses< ElemTy >::end(), F, llvm::EquivalenceClasses< ElemTy >::findValue(), llvm::DSGraph::getGlobalECs(), getParentGraph(), globals_begin(), globals_end(), llvm::EquivalenceClasses< ElemTy >::member_begin(), llvm::EquivalenceClasses< ElemTy >::member_end(), and MI.
Referenced by GetAllCallees(), and nodeContainsExternalFunction().
void DSNode::addFullGlobalsList | ( | std::vector< GlobalValue * > & | List | ) | const |
addFullGlobalsList - Compute the full set of global values that are represented by this node. Unlike getGlobalsList(), this requires fair amount of work to compute, so don't treat this method call as free.
Definition at line 260 of file DataStructure.cpp.
References E, llvm::EquivalenceClasses< ElemTy >::end(), llvm::EquivalenceClasses< ElemTy >::findValue(), llvm::DSGraph::getGlobalECs(), getParentGraph(), globals_begin(), globals_end(), llvm::EquivalenceClasses< ElemTy >::member_begin(), and llvm::EquivalenceClasses< ElemTy >::member_end().
void DSNode::addGlobal | ( | GlobalValue * | GV | ) |
addGlobal - Add an entry for a global value to the Globals list. This also marks the node with the 'G' flag if it does not already have it.
Definition at line 178 of file DataStructure.cpp.
References getParentGraph(), llvm::DSGraph::getScalarMap(), GlobalNode, and GV.
Referenced by llvm::DSGraph::addObjectToGraph(), and EliminateUsesOfECGlobals().
void DSNode::assertOK | ( | ) | const |
Definition at line 142 of file DataStructure.cpp.
References Array, llvm::DSScalarMap::find(), llvm::DSNodeIterator< NodeTy >::getNode(), llvm::DSGraph::getScalarMap(), llvm::DSScalarMap::global_count(), and llvm::Type::VoidTy.
DSNode::const_iterator llvm::DSNode::begin | ( | ) | const [inline] |
Definition at line 87 of file DSGraphTraits.h.
DSNode::iterator llvm::DSNode::begin | ( | ) | [inline] |
Definition at line 81 of file DSGraphTraits.h.
Referenced by llvm::GraphTraits< const DSGraph * >::child_begin(), llvm::GraphTraits< DSGraph * >::child_begin(), llvm::GraphTraits< const DSNode * >::child_begin(), llvm::GraphTraits< DSNode * >::child_begin(), and llvm::DOTGraphTraits< const DSGraph * >::getEdgeTarget().
void llvm::DSNode::dropAllReferences | ( | ) | [inline] |
Definition at line 370 of file DSNode.h.
References isForwarding(), and llvm::DSNodeHandle::setTo().
Referenced by ~DSNode().
void DSNode::dump | ( | ) | const |
const_edge_iterator llvm::DSNode::edge_begin | ( | ) | const [inline] |
edge_iterator llvm::DSNode::edge_begin | ( | ) | [inline] |
Definition at line 220 of file DSNode.h.
Referenced by markIncompleteNode(), and markReachableNodes().
const_edge_iterator llvm::DSNode::edge_end | ( | ) | const [inline] |
edge_iterator llvm::DSNode::edge_end | ( | ) | [inline] |
Definition at line 221 of file DSNode.h.
Referenced by markIncompleteNode(), and markReachableNodes().
DSNode::const_iterator llvm::DSNode::end | ( | ) | const [inline] |
Definition at line 90 of file DSGraphTraits.h.
DSNode::iterator llvm::DSNode::end | ( | ) | [inline] |
Definition at line 84 of file DSGraphTraits.h.
Referenced by llvm::GraphTraits< const DSGraph * >::child_end(), llvm::GraphTraits< DSGraph * >::child_end(), llvm::GraphTraits< const DSNode * >::child_end(), and llvm::GraphTraits< DSNode * >::child_end().
void DSNode::foldNodeCompletely | ( | ) |
foldNodeCompletely - If we determine that this node has some funny behavior happening to it that we cannot represent, we fold it down to a single, completely pessimistic, node. This node is represented as a single byte with a single TypeEntry of "void" with isArray = true.
Definition at line 207 of file DataStructure.cpp.
References Array, forwardNode(), llvm::DSNodeHandle::getNode(), getSize(), Globals, isNodeCompletelyFolded(), Links, NodeType, NumFolds, Size, Ty, and llvm::Type::VoidTy.
Referenced by llvm::ReachabilityCloner::merge(), mergeTypeInfo(), and mergeWith().
void DSNode::forwardNode | ( | DSNode * | To, | |
unsigned | Offset | |||
) |
forwardNode - Mark this node as being obsolete, and all references to it should be forwarded to the specified node and offset.
Definition at line 159 of file DataStructure.cpp.
References DEAD, llvm::DSNodeHandle::isNull(), llvm::DSNodeHandle::setTo(), Size, llvm::DSGraph::unlinkNode(), and llvm::Type::VoidTy.
Referenced by foldNodeCompletely().
DSNode* llvm::DSNode::getForwardNode | ( | ) | const [inline] |
getForwardNode - This method returns the node that this node is forwarded to, if any.
Definition at line 167 of file DSNode.h.
References llvm::DSNodeHandle::getNode().
Referenced by CanReachAliveNodes(), and markReachableNodes().
const std::vector<GlobalValue*>& llvm::DSNode::getGlobalsList | ( | ) | const [inline] |
getGlobalsList - Return the set of global leaders that are represented by this node. Note that globals that are in this equivalence class but are not leaders are not returned: for that, use addFullGlobalsList().
Definition at line 297 of file DSNode.h.
Referenced by getCaption(), llvm::ReachabilityCloner::getClonedNH(), llvm::ReachabilityCloner::merge(), and removeIdenticalCalls().
const DSNodeHandle& llvm::DSNode::getLink | ( | unsigned | Offset | ) | const [inline] |
DSNodeHandle& llvm::DSNode::getLink | ( | unsigned | Offset | ) | [inline] |
getLink - Return the link at the specified offset.
Definition at line 197 of file DSNode.h.
References llvm::DS::PointerShift.
Referenced by addEdgeTo(), llvm::DSGraph::computeNodeMapping(), llvm::DOTGraphTraits< const DSGraph * >::edgeTargetsEdgeSource(), llvm::ReachabilityCloner::getClonedNH(), llvm::DOTGraphTraits< const DSGraph * >::getEdgeTarget(), llvm::DSNodeHandle::getLink(), and llvm::ReachabilityCloner::merge().
unsigned llvm::DSNode::getNodeFlags | ( | ) | const [inline] |
getNodeFlags - Return all of the flags set on the node. If the DEAD flag is set, hide it from the caller.
Definition at line 330 of file DSNode.h.
References DEAD.
Referenced by getCaption(), and llvm::ReachabilityCloner::merge().
unsigned llvm::DSNode::getNumLinks | ( | ) | const [inline] |
getNumLinks - Return the number of links in a node...
Definition at line 214 of file DSNode.h.
Referenced by llvm::ReachabilityCloner::getClonedNH(), and llvm::ReachabilityCloner::merge().
unsigned llvm::DSNode::getNumReferrers | ( | ) | const [inline] |
getNumReferrers - This method returns the number of referrers to the current node. Note that if this node is a forwarding node, this will return the number of nodes forwarding over the node!
Definition at line 154 of file DSNode.h.
Referenced by hasNoReferrers(), and removeIdenticalCalls().
DSGraph* llvm::DSNode::getParentGraph | ( | ) | const [inline] |
Definition at line 156 of file DSNode.h.
Referenced by addFullFunctionList(), addFullGlobalsList(), addGlobal(), llvm::DSGraph::AssertNodeInGraph(), getCaption(), and mergeTypeInfo().
unsigned llvm::DSNode::getPointerSize | ( | ) | const [inline] |
getPointerSize - Return the size of a pointer for the current target.
Definition at line 266 of file DSNode.h.
References llvm::DS::PointerSize.
unsigned llvm::DSNode::getSize | ( | ) | const [inline] |
getSize - Return the maximum number of bytes occupied by this object...
Definition at line 139 of file DSNode.h.
Referenced by llvm::DSGraph::computeNodeMapping(), foldNodeCompletely(), llvm::ReachabilityCloner::getClonedNH(), isNodeCompletelyFolded(), llvm::ReachabilityCloner::merge(), and mergeWith().
const TargetData & DSNode::getTargetData | ( | ) | const |
getTargetData - Get the target data object used to construct this node.
Definition at line 138 of file DataStructure.cpp.
References llvm::DSGraph::getTargetData().
Referenced by mergeTypeInfo().
const Type* llvm::DSNode::getType | ( | ) | const [inline] |
getType - Return the node type of this object...
Definition at line 143 of file DSNode.h.
References Ty.
Referenced by getCaption(), and llvm::ReachabilityCloner::merge().
globals_iterator llvm::DSNode::globals_begin | ( | ) | const [inline] |
Definition at line 313 of file DSNode.h.
Referenced by addFullFunctionList(), addFullGlobalsList(), llvm::DSGraph::AssertNodeContainsGlobal(), llvm::ReachabilityCloner::getClonedNH(), and llvm::ReachabilityCloner::merge().
globals_iterator llvm::DSNode::globals_end | ( | ) | const [inline] |
Definition at line 314 of file DSNode.h.
Referenced by addFullFunctionList(), addFullGlobalsList(), llvm::DSGraph::AssertNodeContainsGlobal(), llvm::ReachabilityCloner::getClonedNH(), and llvm::ReachabilityCloner::merge().
bool llvm::DSNode::hasLink | ( | unsigned | Offset | ) | const [inline] |
hasLink - Return true if this memory object has a link in slot LinkNo
Definition at line 187 of file DSNode.h.
References llvm::DS::PointerShift.
Referenced by llvm::DSNodeHandle::hasLink().
bool llvm::DSNode::hasNoReferrers | ( | ) | const [inline] |
hasNoReferrers - Return true if nothing is pointing to this node at all.
Definition at line 149 of file DSNode.h.
References getNumReferrers().
Referenced by makeNodeDead(), mergeWith(), and ~DSNode().
bool llvm::DSNode::isAllocaNode | ( | ) | const [inline] |
bool llvm::DSNode::isArray | ( | ) | const [inline] |
Definition at line 145 of file DSNode.h.
References Array.
Referenced by getCaption(), isNodeCompletelyFolded(), llvm::ReachabilityCloner::merge(), and mergeTypeInfo().
bool llvm::DSNode::isComplete | ( | ) | const [inline] |
Definition at line 341 of file DSNode.h.
References isIncomplete().
Referenced by removeIdenticalCalls().
bool llvm::DSNode::isDeadNode | ( | ) | const [inline] |
Definition at line 342 of file DSNode.h.
References DEAD.
Referenced by llvm::ReachabilityCloner::merge(), and mergeWith().
bool llvm::DSNode::isForwarding | ( | ) | const [inline] |
isForwarding - Return true if this node is forwarding to another.
Definition at line 171 of file DSNode.h.
References llvm::DSNodeHandle::isNull().
Referenced by dropAllReferences(), llvm::DSNodeHandle::getNode(), llvm::DSNodeHandle::setTo(), and stopForwarding().
bool llvm::DSNode::isGlobalNode | ( | ) | const [inline] |
bool llvm::DSNode::isHeapNode | ( | ) | const [inline] |
bool llvm::DSNode::isIncomplete | ( | ) | const [inline] |
Definition at line 340 of file DSNode.h.
References Incomplete.
Referenced by GetAllCallees(), isComplete(), and markIncompleteNode().
bool llvm::DSNode::isModified | ( | ) | const [inline] |
bool DSNode::isNodeCompletelyFolded | ( | ) | const |
isNodeCompletelyFolded - Return true if this node has been completely folded down to something that can never be expanded, effectively losing all of the field sensitivity that may be present in the node.
Definition at line 253 of file DataStructure.cpp.
References getSize(), isArray(), and llvm::Type::VoidTy.
Referenced by addEdgeTo(), llvm::DSGraph::computeNodeMapping(), foldNodeCompletely(), getCaption(), llvm::ReachabilityCloner::merge(), and mergeTypeInfo().
bool llvm::DSNode::isRead | ( | ) | const [inline] |
bool llvm::DSNode::isUnknownNode | ( | ) | const [inline] |
void llvm::DSNode::makeNodeDead | ( | ) | [inline] |
void DSNode::markReachableNodes | ( | hash_set< const DSNode * > & | ReachableNodes | ) | const |
markReachableNodes - This method recursively traverses the specified DSNodes, marking any nodes which are reachable. All reachable nodes it adds to the set, which allows it to only traverse visited nodes once.
Definition at line 1986 of file DataStructure.cpp.
References E, edge_begin(), edge_end(), and getForwardNode().
Referenced by llvm::DSCallSite::markReachableNodes(), and llvm::DSGraph::removeDeadNodes().
void llvm::DSNode::maskNodeTypes | ( | unsigned | Mask | ) | [inline] |
maskNodeTypes - Apply a mask to the node types bitfield.
Definition at line 319 of file DSNode.h.
Referenced by llvm::DSGraph::cloneInto(), and llvm::ReachabilityCloner::merge().
void DSNode::mergeGlobals | ( | const std::vector< GlobalValue * > & | RHS | ) |
Definition at line 760 of file DataStructure.cpp.
References MergeSortedVectors().
Referenced by llvm::ReachabilityCloner::getClonedNH(), and llvm::ReachabilityCloner::merge().
void llvm::DSNode::mergeNodeFlags | ( | unsigned | RHS | ) | [inline] |
bool DSNode::mergeTypeInfo | ( | const Type * | Ty, | |
unsigned | Offset, | |||
bool | FoldIfIncompatible = true | |||
) |
mergeTypeInfo - This method merges the specified type into the current node at the specified offset. This may update the current node's type record if this gives more information to the node, it may do nothing to the node if this information is already known, or it may merge the node completely (and return true) if the information is incompatible with what is already known.
This method returns true if the node is completely folded, otherwise false.
Definition at line 422 of file DataStructure.cpp.
References abort(), Array, llvm::Type::ArrayTyID, DEBUG, DSAFieldLimit, llvm::StructType::element_begin(), llvm::StructType::element_end(), ElementTypesAreCompatible(), foldNodeCompletely(), llvm::StructType::get(), llvm::StructLayout::getElementContainingOffset(), llvm::StructType::getElementType(), llvm::SequentialType::getElementType(), getParentGraph(), llvm::TargetData::getStructLayout(), getTargetData(), llvm::Type::getTypeID(), llvm::TargetData::getTypeSize(), isArray(), isNodeCompletelyFolded(), llvm::Type::isSized(), M, llvm::StructLayout::MemberOffsets, O, llvm::DS::PointerShift, llvm::DS::PointerSize, llvm::DSGraph::retnodes_begin(), llvm::DSGraph::retnodes_end(), llvm::Type::StructTyID, TD, llvm::Type::VoidTy, and llvm::WriteTypeSymbolic().
Referenced by DSNode(), and llvm::ReachabilityCloner::merge().
void DSNode::mergeWith | ( | const DSNodeHandle & | NH, | |
unsigned | Offset | |||
) |
mergeWith - Merge this node and the specified node, moving all links to and from the argument node into the current node, deleting the node argument. Offset indicates what offset the specified node is to be merged into the current node.
The specified node may be a null pointer (in which case, nothing happens).
Definition at line 878 of file DataStructure.cpp.
References DEBUG, DSNodeHandle, foldNodeCompletely(), llvm::DSNodeHandle::getNode(), llvm::DSNodeHandle::getOffset(), getSize(), hasNoReferrers(), isDeadNode(), mergeWith(), and llvm::DSNodeHandle::mergeWith().
Referenced by llvm::DSNodeHandle::mergeWith(), and mergeWith().
void DSNode::print | ( | std::ostream & | O, | |
const DSGraph * | G | |||
) | const |
Definition at line 230 of file Printer.cpp.
References G, and llvm::GraphWriter< GraphType >::writeNode().
Referenced by dump().
void llvm::DSNode::remapLinks | ( | hash_map< const DSNode *, DSNodeHandle > & | OldNodeMap | ) |
remapLinks - Change all of the Links in the current node according to the specified mapping.
void DSNode::removeGlobal | ( | GlobalValue * | GV | ) |
removeGlobal - Remove the specified global that is explicitly in the globals list.
Definition at line 195 of file DataStructure.cpp.
References GV.
Referenced by EliminateUsesOfECGlobals().
DSNode* llvm::DSNode::setAllocaNodeMarker | ( | ) | [inline] |
Definition at line 344 of file DSNode.h.
References AllocaNode.
Referenced by llvm::DSGraph::addObjectToGraph().
DSNode* llvm::DSNode::setArrayMarker | ( | ) | [inline] |
DSNode* llvm::DSNode::setGlobalNodeMarker | ( | ) | [inline] |
DSNode* llvm::DSNode::setHeapNodeMarker | ( | ) | [inline] |
Definition at line 345 of file DSNode.h.
References HeapNode.
Referenced by llvm::DSGraph::addObjectToGraph().
DSNode* llvm::DSNode::setIncompleteMarker | ( | ) | [inline] |
void llvm::DSNode::setLink | ( | unsigned | Offset, | |
const DSNodeHandle & | NH | |||
) | [inline] |
setLink - Set the link at the specified offset to the specified NodeHandle, replacing what was there. It is uncommon to use this method, instead one of the higher level methods should be used, below.
Definition at line 256 of file DSNode.h.
References llvm::DS::PointerShift.
Referenced by addEdgeTo(), and llvm::DSNodeHandle::setLink().
DSNode* llvm::DSNode::setModifiedMarker | ( | ) | [inline] |
void llvm::DSNode::setParentGraph | ( | DSGraph * | G | ) | [inline] |
DSNode* llvm::DSNode::setReadMarker | ( | ) | [inline] |
DSNode* llvm::DSNode::setUnknownNodeMarker | ( | ) | [inline] |
void llvm::DSNode::stopForwarding | ( | ) | [inline] |
stopForwarding - When the last reference to this forwarding node has been dropped, delete the node.
Definition at line 176 of file DSNode.h.
References isForwarding(), and llvm::DSNodeHandle::setTo().
friend class DSNodeHandle [friend] |