forked from OSchip/llvm-project
MEGAPATCH checkin.
For details, See: docs/2002-06-25-MegaPatchInfo.txt llvm-svn: 2779
This commit is contained in:
parent
7076ff29ed
commit
113f4f4609
|
@ -8,51 +8,196 @@
|
|||
#ifndef SUPPORT_CASTING_H
|
||||
#define SUPPORT_CASTING_H
|
||||
|
||||
// real_type - Provide a macro to get the real type of a value that might be
|
||||
// a use. This provides a typedef 'Type' that is the argument type for all
|
||||
// non UseTy types, and is the contained pointer type of the use if it is a
|
||||
// UseTy.
|
||||
//
|
||||
template <class X> class real_type { typedef X Type; };
|
||||
#include <assert.h>
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Type Checking Templates
|
||||
// isa<x> Support Templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template<typename FromCl> struct isa_impl_cl;
|
||||
|
||||
// Define a template that can be specialized by smart pointers to reflect the
|
||||
// fact that they are automatically dereferenced, and are not involved with the
|
||||
// template selection process... the default implementation is a noop.
|
||||
//
|
||||
template<typename From> struct simplify_type {
|
||||
typedef From SimpleType; // The real type this represents...
|
||||
|
||||
// An accessor to get the real value...
|
||||
static SimpleType &getSimplifiedValue(From &Val) { return Val; }
|
||||
};
|
||||
|
||||
template<typename From> struct simplify_type<const From> {
|
||||
typedef const From SimpleType;
|
||||
static SimpleType &getSimplifiedValue(const From &Val) {
|
||||
return simplify_type<From>::getSimplifiedValue((From&)Val);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// isa<X> - Return true if the parameter to the template is an instance of the
|
||||
// template type argument. Used like this:
|
||||
//
|
||||
// if (isa<Type>(myVal)) { ... }
|
||||
// if (isa<Type*>(myVal)) { ... }
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline bool isa(Y Val) {
|
||||
assert(Val && "isa<Ty>(NULL) invoked!");
|
||||
return X::classof(Val);
|
||||
template <typename To, typename From>
|
||||
inline bool isa_impl(const From &Val) {
|
||||
return To::classof(&Val);
|
||||
}
|
||||
|
||||
template<typename To, typename From, typename SimpleType>
|
||||
struct isa_impl_wrap {
|
||||
// When From != SimplifiedType, we can simplify the type some more by using
|
||||
// the simplify_type template.
|
||||
static bool doit(const From &Val) {
|
||||
return isa_impl_cl<const SimpleType>::template
|
||||
isa<To>(simplify_type<const From>::getSimplifiedValue(Val));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename To, typename FromTy>
|
||||
struct isa_impl_wrap<To, const FromTy, const FromTy> {
|
||||
// When From == SimpleType, we are as simple as we are going to get.
|
||||
static bool doit(const FromTy &Val) {
|
||||
return isa_impl<To,FromTy>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
// isa_impl_cl - Use class partial specialization to transform types to a single
|
||||
// cannonical form for isa_impl.
|
||||
//
|
||||
template<typename FromCl>
|
||||
struct isa_impl_cl {
|
||||
template<class ToCl>
|
||||
static bool isa(const FromCl &Val) {
|
||||
return isa_impl_wrap<ToCl,const FromCl,
|
||||
simplify_type<const FromCl>::SimpleType>::doit(Val);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization used to strip const qualifiers off of the FromCl type...
|
||||
template<typename FromCl>
|
||||
struct isa_impl_cl<const FromCl> {
|
||||
template<class ToCl>
|
||||
static bool isa(const FromCl &Val) {
|
||||
return isa_impl_cl<FromCl>::template isa<ToCl>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
// Define pointer traits in terms of base traits...
|
||||
template<class FromCl>
|
||||
struct isa_impl_cl<FromCl*> {
|
||||
template<class ToCl>
|
||||
static bool isa(FromCl *Val) {
|
||||
return isa_impl_cl<FromCl>::template isa<ToCl>(*Val);
|
||||
}
|
||||
};
|
||||
|
||||
// Define reference traits in terms of base traits...
|
||||
template<class FromCl>
|
||||
struct isa_impl_cl<FromCl&> {
|
||||
template<class ToCl>
|
||||
static bool isa(FromCl &Val) {
|
||||
return isa_impl_cl<FromCl>::template isa<ToCl>(&Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <class X, class Y>
|
||||
inline bool isa(const Y &Val) {
|
||||
return isa_impl_cl<Y>::template isa<X>(Val);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// cast<x> Support Templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template<class To, class From> struct cast_retty;
|
||||
|
||||
|
||||
// Calculate what type the 'cast' function should return, based on a requested
|
||||
// type of To and a source type of From.
|
||||
template<class To, class From> struct cast_retty_impl {
|
||||
typedef To& ret_type; // Normal case, return Ty&
|
||||
};
|
||||
template<class To, class From> struct cast_retty_impl<To, const From> {
|
||||
typedef const To &ret_type; // Normal case, return Ty&
|
||||
};
|
||||
|
||||
template<class To, class From> struct cast_retty_impl<To, From*> {
|
||||
typedef To* ret_type; // Pointer arg case, return Ty*
|
||||
};
|
||||
|
||||
template<class To, class From> struct cast_retty_impl<To, const From*> {
|
||||
typedef const To* ret_type; // Constant pointer arg case, return const Ty*
|
||||
};
|
||||
|
||||
template<class To, class From> struct cast_retty_impl<To, const From*const> {
|
||||
typedef const To* ret_type; // Constant pointer arg case, return const Ty*
|
||||
};
|
||||
|
||||
|
||||
template<class To, class From, class SimpleFrom>
|
||||
struct cast_retty_wrap {
|
||||
// When the simplified type and the from type are not the same, use the type
|
||||
// simplifier to reduce the type, then reuse cast_retty_impl to get the
|
||||
// resultant type.
|
||||
typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
|
||||
};
|
||||
|
||||
template<class To, class FromTy>
|
||||
struct cast_retty_wrap<To, FromTy, FromTy> {
|
||||
// When the simplified type is equal to the from type, use it directly.
|
||||
typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
|
||||
};
|
||||
|
||||
template<class To, class From>
|
||||
struct cast_retty {
|
||||
typedef typename cast_retty_wrap<To, From,
|
||||
simplify_type<From>::SimpleType>::ret_type ret_type;
|
||||
};
|
||||
|
||||
// Ensure the non-simple values are converted using the simplify_type template
|
||||
// that may be specialized by smart pointers...
|
||||
//
|
||||
template<class To, class From, class SimpleFrom> struct cast_convert_val {
|
||||
// This is not a simple type, use the template to simplify it...
|
||||
static cast_retty<To, From>::ret_type doit(const From &Val) {
|
||||
return cast_convert_val<To, SimpleFrom,
|
||||
simplify_type<SimpleFrom>::SimpleType>::doit(
|
||||
simplify_type<From>::getSimplifiedValue(Val));
|
||||
}
|
||||
};
|
||||
|
||||
template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
|
||||
// This _is_ a simple type, just cast it.
|
||||
static cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
|
||||
return (cast_retty<To, FromTy>::ret_type)Val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// cast<X> - Return the argument parameter cast to the specified type. This
|
||||
// casting operator asserts that the type is correct, so it does not return null
|
||||
// on failure. But it will correctly return NULL when the input is NULL.
|
||||
// Used Like this:
|
||||
//
|
||||
// cast< Instruction>(myVal)->getParent()
|
||||
// cast<const Instruction>(myVal)->getParent()
|
||||
// cast<Instruction>(myVal)->getParent()
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline X *cast(Y Val) {
|
||||
inline cast_retty<X, Y>::ret_type cast(const Y &Val) {
|
||||
assert(isa<X>(Val) && "cast<Ty>() argument of uncompatible type!");
|
||||
return (X*)(real_type<Y>::Type)Val;
|
||||
return cast_convert_val<X, Y, simplify_type<Y>::SimpleType>::doit(Val);
|
||||
}
|
||||
|
||||
// cast_or_null<X> - Functionally identical to cast, except that a null value is
|
||||
// accepted.
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline X *cast_or_null(Y Val) {
|
||||
assert((Val == 0 || isa<X>(Val)) &&
|
||||
"cast_or_null<Ty>() argument of uncompatible type!");
|
||||
return (X*)(real_type<Y>::Type)Val;
|
||||
inline cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
|
||||
if (Val == 0) return 0;
|
||||
assert(isa<X>(Val) && "cast_or_null<Ty>() argument of uncompatible type!");
|
||||
return cast<X>(Val);
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,16 +210,81 @@ inline X *cast_or_null(Y Val) {
|
|||
//
|
||||
|
||||
template <class X, class Y>
|
||||
inline X *dyn_cast(Y Val) {
|
||||
return isa<X>(Val) ? cast<X>(Val) : 0;
|
||||
inline cast_retty<X, Y*>::ret_type dyn_cast(Y *Val) {
|
||||
return isa<X>(Val) ? cast<X, Y*>(Val) : 0;
|
||||
}
|
||||
|
||||
// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
|
||||
// value is accepted.
|
||||
//
|
||||
template <class X, class Y>
|
||||
inline X *dyn_cast_or_null(Y Val) {
|
||||
return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
|
||||
inline cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
|
||||
return (Val && isa<X>(Val)) ? cast<X, Y*>(Val) : 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_CAST_OPERATORS
|
||||
#include <iostream>
|
||||
|
||||
struct bar {
|
||||
bar() {}
|
||||
private:
|
||||
bar(const bar &);
|
||||
};
|
||||
struct foo {
|
||||
void ext() const;
|
||||
/* static bool classof(const bar *X) {
|
||||
cerr << "Classof: " << X << "\n";
|
||||
return true;
|
||||
}*/
|
||||
};
|
||||
|
||||
template <> inline bool isa_impl<foo,bar>(const bar &Val) {
|
||||
cerr << "Classof: " << &Val << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bar *fub();
|
||||
void test(bar &B1, const bar *B2) {
|
||||
// test various configurations of const
|
||||
const bar &B3 = B1;
|
||||
const bar *const B4 = B2;
|
||||
|
||||
// test isa
|
||||
if (!isa<foo>(B1)) return;
|
||||
if (!isa<foo>(B2)) return;
|
||||
if (!isa<foo>(B3)) return;
|
||||
if (!isa<foo>(B4)) return;
|
||||
|
||||
// test cast
|
||||
foo &F1 = cast<foo>(B1);
|
||||
const foo *F3 = cast<foo>(B2);
|
||||
const foo *F4 = cast<foo>(B2);
|
||||
const foo &F8 = cast<foo>(B3);
|
||||
const foo *F9 = cast<foo>(B4);
|
||||
foo *F10 = cast<foo>(fub());
|
||||
|
||||
// test cast_or_null
|
||||
const foo *F11 = cast_or_null<foo>(B2);
|
||||
const foo *F12 = cast_or_null<foo>(B2);
|
||||
const foo *F13 = cast_or_null<foo>(B4);
|
||||
const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
|
||||
|
||||
// These lines are errors...
|
||||
//foo *F20 = cast<foo>(B2); // Yields const foo*
|
||||
//foo &F21 = cast<foo>(B3); // Yields const foo&
|
||||
//foo *F22 = cast<foo>(B4); // Yields const foo*
|
||||
//foo &F23 = cast_or_null<foo>(B1);
|
||||
//const foo &F24 = cast_or_null<foo>(B3);
|
||||
}
|
||||
|
||||
bar *fub() { return 0; }
|
||||
void main() {
|
||||
bar B;
|
||||
test(B, &B);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,492 @@
|
|||
//===-- <Support/ilist> - Intrusive Linked List Template ---------*- C++ -*--=//
|
||||
//
|
||||
// This file defines classes to implement an intrusive doubly linked list class
|
||||
// (ie each node of the list must contain a next and previous field for the
|
||||
// list.
|
||||
//
|
||||
// The ilist_traits trait class is used to gain access to the next and previous
|
||||
// fields of the node type that the list is instantiated with. If it is not
|
||||
// specialized, the list defaults to using the getPrev(), getNext() method calls
|
||||
// to get the next and previous pointers.
|
||||
//
|
||||
// The ilist class itself, should be a plug in replacement for list, assuming
|
||||
// that the nodes contain next/prev pointers. This list replacement does not
|
||||
// provides a constant time size() method, so be careful to use empty() when you
|
||||
// really want to know if I'm empty.
|
||||
//
|
||||
// The ilist class is implemented by allocating a 'tail' node when the list is
|
||||
// created (using ilist_traits<>::createEndMarker()). This tail node is
|
||||
// absolutely required because the user must be able to compute end()-1. Because
|
||||
// of this, users of the direct next/prev links will see an extra link on the
|
||||
// end of the list, which should be ignored.
|
||||
//
|
||||
// Requirements for a user of this list:
|
||||
//
|
||||
// 1. The user must provide {g|s}et{Next|Prev} methods, or specialize
|
||||
// ilist_traits to provide an alternate way of getting and setting next and
|
||||
// prev links.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef INCLUDED_SUPPORT_ILIST
|
||||
#define INCLUDED_SUPPORT_ILIST
|
||||
|
||||
#include <assert.h>
|
||||
#include <iterator>
|
||||
|
||||
template<typename NodeTy, typename Traits> class iplist;
|
||||
template<typename NodeTy> class ilist_iterator;
|
||||
|
||||
// Template traits for intrusive list. By specializing this template class, you
|
||||
// can change what next/prev fields are used to store the links...
|
||||
template<typename NodeTy>
|
||||
struct ilist_traits {
|
||||
static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
|
||||
static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
|
||||
static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
|
||||
static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
|
||||
|
||||
static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
|
||||
static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
|
||||
|
||||
static NodeTy *createNode() { return new NodeTy(); }
|
||||
static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
|
||||
|
||||
|
||||
void addNodeToList(NodeTy *NTy) {}
|
||||
void removeNodeFromList(NodeTy *NTy) {}
|
||||
void transferNodesFromList(iplist<NodeTy, ilist_traits> &L2,
|
||||
ilist_iterator<NodeTy> first,
|
||||
ilist_iterator<NodeTy> last) {}
|
||||
};
|
||||
|
||||
// Const traits are the same as nonconst traits...
|
||||
template<typename Ty>
|
||||
struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ilist_iterator<Node> - Iterator for intrusive list.
|
||||
//
|
||||
template<typename NodeTy>
|
||||
class ilist_iterator : public std::bidirectional_iterator<NodeTy, ptrdiff_t> {
|
||||
typedef ilist_traits<NodeTy> Traits;
|
||||
pointer NodePtr;
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
|
||||
ilist_iterator(pointer NP) : NodePtr(NP) {}
|
||||
ilist_iterator() : NodePtr(0) {}
|
||||
|
||||
// This is templated so that we can allow constructing a const iterator from
|
||||
// a nonconst iterator...
|
||||
template<class node_ty>
|
||||
ilist_iterator(const ilist_iterator<node_ty> &RHS)
|
||||
: NodePtr(RHS.getNodePtrUnchecked()) {}
|
||||
|
||||
// This is templated so that we can allow assigning to a const iterator from
|
||||
// a nonconst iterator...
|
||||
template<class node_ty>
|
||||
const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
|
||||
NodePtr = RHS.getNodePtrUnchecked();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Accessors...
|
||||
operator pointer() const {
|
||||
assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
|
||||
return NodePtr;
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
|
||||
return *NodePtr;
|
||||
}
|
||||
pointer operator->() { return &operator*(); }
|
||||
const pointer operator->() const { return &operator*(); }
|
||||
|
||||
// Comparison operators
|
||||
bool operator==(const ilist_iterator &RHS) const {
|
||||
return NodePtr == RHS.NodePtr;
|
||||
}
|
||||
bool operator!=(const ilist_iterator &RHS) const {
|
||||
return NodePtr != RHS.NodePtr;
|
||||
}
|
||||
|
||||
// Increment and decrement operators...
|
||||
ilist_iterator &operator--() { // predecrement - Back up
|
||||
NodePtr = Traits::getPrev(NodePtr);
|
||||
assert(NodePtr && "--'d off the beginning of an ilist!");
|
||||
return *this;
|
||||
}
|
||||
ilist_iterator &operator++() { // preincrement - Advance
|
||||
NodePtr = Traits::getNext(NodePtr);
|
||||
assert(NodePtr && "++'d off the end of an ilist!");
|
||||
return *this;
|
||||
}
|
||||
ilist_iterator operator--(int) { // postdecrement operators...
|
||||
ilist_iterator tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
ilist_iterator operator++(int) { // postincrement operators...
|
||||
ilist_iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
// Dummy operators to make errors apparent...
|
||||
template<class X> void operator+(X Val) {}
|
||||
template<class X> void operator-(X Val) {}
|
||||
|
||||
// Internal interface, do not use...
|
||||
pointer getNodePtrUnchecked() const { return NodePtr; }
|
||||
};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// iplist - The subset of list functionality that can safely be used on nodes of
|
||||
// polymorphic types, ie a heterogeneus list with a common base class that holds
|
||||
// the next/prev pointers...
|
||||
//
|
||||
template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
|
||||
class iplist : public Traits {
|
||||
NodeTy *Head, *Tail;
|
||||
|
||||
static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
|
||||
static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
|
||||
public:
|
||||
typedef NodeTy *pointer;
|
||||
typedef const NodeTy *const_pointer;
|
||||
typedef NodeTy &reference;
|
||||
typedef const NodeTy &const_reference;
|
||||
typedef NodeTy value_type;
|
||||
typedef ilist_iterator<NodeTy> iterator;
|
||||
typedef ilist_iterator<const NodeTy> const_iterator;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
iplist() : Head(createNode()), Tail(Head) {
|
||||
setNext(Head, 0);
|
||||
setPrev(Head, 0);
|
||||
}
|
||||
~iplist() { clear(); delete Tail; }
|
||||
|
||||
// Iterator creation methods...
|
||||
iterator begin() { return iterator(Head); }
|
||||
const_iterator begin() const { return const_iterator(Head); }
|
||||
iterator end() { return iterator(Tail); }
|
||||
const_iterator end() const { return const_iterator(Tail); }
|
||||
|
||||
// reverse iterator creation methods...
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
|
||||
|
||||
// Miscellaneous inspection routines...
|
||||
size_type max_size() const { return size_type(-1); }
|
||||
bool empty() const { return Head == Tail; }
|
||||
|
||||
// Front and back accessor functions...
|
||||
reference front() {
|
||||
assert(!empty() && "Called front() on empty list!");
|
||||
return *Head;
|
||||
}
|
||||
const_reference front() const {
|
||||
assert(!empty() && "Called front() on empty list!");
|
||||
return *Head;
|
||||
}
|
||||
reference back() {
|
||||
assert(!empty() && "Called back() on empty list!");
|
||||
return *getPrev(Tail);
|
||||
}
|
||||
const_reference back() const {
|
||||
assert(!empty() && "Called back() on empty list!");
|
||||
return *getPrev(Tail);
|
||||
}
|
||||
|
||||
void swap(iplist &RHS) {
|
||||
abort(); // Swap does not use list traits callback correctly yet!
|
||||
std::swap(Head, RHS.Head);
|
||||
std::swap(Tail, RHS.Tail);
|
||||
}
|
||||
|
||||
iterator insert(iterator where, NodeTy *New) {
|
||||
NodeTy *CurNode = where.getNodePtrUnchecked(), *PrevNode = getPrev(CurNode);
|
||||
setNext(New, CurNode);
|
||||
setPrev(New, PrevNode);
|
||||
|
||||
if (PrevNode)
|
||||
setNext(PrevNode, New);
|
||||
else
|
||||
Head = New;
|
||||
setPrev(CurNode, New);
|
||||
|
||||
addNodeToList(New); // Notify traits that we added a node...
|
||||
return New;
|
||||
}
|
||||
|
||||
NodeTy *remove(iterator &IT) {
|
||||
assert(IT != end() && "Cannot remove end of list!");
|
||||
NodeTy *Node = &*IT;
|
||||
NodeTy *NextNode = getNext(Node);
|
||||
NodeTy *PrevNode = getPrev(Node);
|
||||
|
||||
if (PrevNode)
|
||||
setNext(PrevNode, NextNode);
|
||||
else
|
||||
Head = NextNode;
|
||||
setPrev(NextNode, PrevNode);
|
||||
IT = NextNode;
|
||||
removeNodeFromList(Node); // Notify traits that we added a node...
|
||||
return Node;
|
||||
}
|
||||
|
||||
NodeTy *remove(const iterator &IT) {
|
||||
iterator MutIt = IT;
|
||||
return remove(MutIt);
|
||||
}
|
||||
|
||||
// erase - remove a node from the controlled sequence... and delete it.
|
||||
iterator erase(iterator where) {
|
||||
delete remove(where);
|
||||
return where;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// transfer - The heart of the splice function. Move linked list nodes from
|
||||
// [first, last) into position.
|
||||
//
|
||||
void transfer(iterator position, iplist &L2, iterator first, iterator last) {
|
||||
assert(first != last && "Should be checked by callers");
|
||||
if (position != last) {
|
||||
// Remove [first, last) from its old position.
|
||||
NodeTy *First = &*first, *Prev = getPrev(First);
|
||||
NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
|
||||
if (Prev)
|
||||
setNext(Prev, Next);
|
||||
else
|
||||
L2.Head = Next;
|
||||
setPrev(Next, Prev);
|
||||
|
||||
// Splice [first, last) into its new position.
|
||||
NodeTy *PosNext = position.getNodePtrUnchecked();
|
||||
NodeTy *PosPrev = getPrev(PosNext);
|
||||
|
||||
// Fix head of list...
|
||||
if (PosPrev)
|
||||
setNext(PosPrev, First);
|
||||
else
|
||||
Head = First;
|
||||
setPrev(First, PosPrev);
|
||||
|
||||
// Fix end of list...
|
||||
setNext(Last, PosNext);
|
||||
setPrev(PosNext, Last);
|
||||
|
||||
transferNodesFromList(L2, First, PosNext);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//===----------------------------------------------------------------------===
|
||||
// Functionality derived from other functions defined above...
|
||||
//
|
||||
|
||||
size_type size() const {
|
||||
size_type Result = 0;
|
||||
std::distance(begin(), end(), Result);
|
||||
return Result;
|
||||
}
|
||||
|
||||
iterator erase(iterator first, iterator last) {
|
||||
while (first != last)
|
||||
first = erase(first);
|
||||
return last;
|
||||
}
|
||||
|
||||
void clear() { erase(begin(), end()); }
|
||||
|
||||
// Front and back inserters...
|
||||
void push_front(NodeTy *val) { insert(begin(), val); }
|
||||
void push_back(NodeTy *val) { insert(end(), val); }
|
||||
void pop_front() {
|
||||
assert(!empty() && "pop_front() on empty list!");
|
||||
erase(begin());
|
||||
}
|
||||
void pop_back() {
|
||||
assert(!empty() && "pop_back() on empty list!");
|
||||
iterator t = end(); erase(--t);
|
||||
}
|
||||
|
||||
// Special forms of insert...
|
||||
template<class InIt> void insert(iterator where, InIt first, InIt last) {
|
||||
for (; first != last; ++first) insert(where, *first);
|
||||
}
|
||||
|
||||
// Splice members - defined in terms of transfer...
|
||||
void splice(iterator where, iplist &L2) {
|
||||
if (!L2.empty())
|
||||
transfer(where, L2, L2.begin(), L2.end());
|
||||
}
|
||||
void splice(iterator where, iplist &L2, iterator first) {
|
||||
iterator last = first; ++last;
|
||||
if (where == first || where == last) return; // No change
|
||||
transfer(where, L2, first, last);
|
||||
}
|
||||
void splice(iterator where, iplist &L2, iterator first, iterator last) {
|
||||
if (first != last) transfer(where, L2, first, last);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===
|
||||
// High-Level Functionality that shouldn't really be here, but is part of list
|
||||
//
|
||||
|
||||
// These two functions are actually called remove/remove_if in list<>, but
|
||||
// they actually do the job of erase, rename them accordingly.
|
||||
//
|
||||
void erase(const NodeTy &val) {
|
||||
for (iterator I = begin(), E = end(); I != E; ) {
|
||||
iterator next = I; ++next;
|
||||
if (*I == val) erase(I);
|
||||
I = next;
|
||||
}
|
||||
}
|
||||
template<class Pr1> void erase_if(Pr1 pred) {
|
||||
for (iterator I = begin(), E = end(); I != E; ) {
|
||||
iterator next = I; ++next;
|
||||
if (pred(*I)) erase(I);
|
||||
I = next;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Pr2> void unique(Pr2 pred) {
|
||||
if (empty()) return;
|
||||
for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
|
||||
if (pred(*I))
|
||||
erase(Next);
|
||||
else
|
||||
I = Next;
|
||||
Next = I;
|
||||
}
|
||||
}
|
||||
void unique() { unique(op_equal); }
|
||||
|
||||
template<class Pr3> void merge(iplist &right, Pr3 pred) {
|
||||
iterator first1 = begin(), last1 = end();
|
||||
iterator first2 = right.begin(), last2 = right.end();
|
||||
while (first1 != last1 && first2 != last2)
|
||||
if (pred(*first2, *first1)) {
|
||||
iterator next = first2;
|
||||
transfer(first1, right, first2, ++next);
|
||||
first2 = next;
|
||||
} else {
|
||||
++first1;
|
||||
}
|
||||
if (first2 != last2) transfer(last1, right, first2, last2);
|
||||
}
|
||||
void merge(iplist &right) { return merge(right, op_less); }
|
||||
|
||||
template<class Pr3> void sort(Pr3 pred);
|
||||
void sort() { sort(op_less); }
|
||||
void reverse();
|
||||
};
|
||||
|
||||
|
||||
template<typename NodeTy>
|
||||
struct ilist : public iplist<NodeTy> {
|
||||
ilist() {}
|
||||
ilist(const ilist &right) {
|
||||
insert(begin(), right.begin(), right.end());
|
||||
}
|
||||
explicit ilist(size_type count) {
|
||||
insert(begin(), count, NodeTy());
|
||||
}
|
||||
ilist(size_type count, const NodeTy &val) {
|
||||
insert(begin(), count, val);
|
||||
}
|
||||
template<class InIt> ilist(InIt first, InIt last) {
|
||||
insert(begin(), first, last);
|
||||
}
|
||||
|
||||
|
||||
// Forwarding functions: A workaround for GCC 2.95 which does not correctly
|
||||
// support 'using' declarations to bring a hidden member into scope.
|
||||
//
|
||||
iterator insert(iterator a, NodeTy *b){ return iplist<NodeTy>::insert(a, b); }
|
||||
void push_front(NodeTy *a) { iplist<NodeTy>::push_front(a); }
|
||||
void push_back(NodeTy *a) { iplist<NodeTy>::push_back(a); }
|
||||
|
||||
|
||||
// Main implementation here - Insert for a node passed by value...
|
||||
iterator insert(iterator where, const NodeTy &val) {
|
||||
return insert(where, createNode(val));
|
||||
}
|
||||
|
||||
|
||||
// Front and back inserters...
|
||||
void push_front(const NodeTy &val) { insert(begin(), val); }
|
||||
void push_back(const NodeTy &val) { insert(end(), val); }
|
||||
|
||||
// Special forms of insert...
|
||||
template<class InIt> void insert(iterator where, InIt first, InIt last) {
|
||||
for (; first != last; ++first) insert(where, *first);
|
||||
}
|
||||
void insert(iterator where, size_type count, const NodeTy &val) {
|
||||
for (; count != 0; --count) insert(where, val);
|
||||
}
|
||||
|
||||
// Assign special forms...
|
||||
void assign(size_type count, const NodeTy &val) {
|
||||
iterator I = begin();
|
||||
for (; I != end() && count != 0; ++I, --count)
|
||||
*I = val;
|
||||
if (count != 0)
|
||||
insert(end(), n, val);
|
||||
else
|
||||
erase(I, end());
|
||||
}
|
||||
template<class InIt> void assign(InIt first, InIt last) {
|
||||
iterator first1 = begin(), last1 = end();
|
||||
for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||
*first1 = *first2;
|
||||
if (first2 == last2)
|
||||
erase(first1, last1);
|
||||
else
|
||||
insert(last1, first2, last2);
|
||||
}
|
||||
|
||||
|
||||
// Resize members...
|
||||
void resize(size_type newsize, NodeTy val) {
|
||||
iterator i = begin();
|
||||
size_type len = 0;
|
||||
for ( ; i != end() && len < newsize; ++i, ++len) /* empty*/ ;
|
||||
|
||||
if (len == newsize)
|
||||
erase(i, end());
|
||||
else // i == end()
|
||||
insert(end(), newsize - len, val);
|
||||
}
|
||||
void resize(size_type newsize) { resize(newsize, NodeTy()); }
|
||||
|
||||
};
|
||||
|
||||
namespace std {
|
||||
// Ensure that swap uses the fast list swap...
|
||||
template<class Ty>
|
||||
void swap(iplist<Ty> &Left, iplist<Ty> &Right) {
|
||||
Left.swap(Right);
|
||||
}
|
||||
} // End 'std' extensions...
|
||||
|
||||
#endif
|
|
@ -118,7 +118,7 @@ public:
|
|||
virtual const char *getPassName() const { return "Call Graph Construction"; }
|
||||
|
||||
// run - Compute the call graph for the specified module.
|
||||
virtual bool run(Module *TheModule);
|
||||
virtual bool run(Module &M);
|
||||
|
||||
// getAnalysisUsage - This obviously provides a call graph
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
|
|
|
@ -442,7 +442,7 @@ public:
|
|||
virtual const char *getPassName() const { return "Data Structure Analysis"; }
|
||||
|
||||
// run - Do nothing, because methods are analyzed lazily
|
||||
virtual bool run(Module *TheModule) { return false; }
|
||||
virtual bool run(Module &TheModule) { return false; }
|
||||
|
||||
// getDSGraph - Return the data structure graph for the specified method.
|
||||
// Since method graphs are lazily computed, we may have to create one on the
|
||||
|
|
|
@ -53,8 +53,8 @@ public:
|
|||
private:
|
||||
DomSetMapType Doms;
|
||||
|
||||
void calcForwardDominatorSet(Function *F);
|
||||
void calcPostDominatorSet(Function *F);
|
||||
void calcForwardDominatorSet(Function &F);
|
||||
void calcPostDominatorSet(Function &F);
|
||||
public:
|
||||
// DominatorSet ctor - Build either the dominator set or the post-dominator
|
||||
// set for a function...
|
||||
|
@ -69,7 +69,7 @@ public:
|
|||
else return "Dominator Set Construction";
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
// Accessor interface:
|
||||
typedef DomSetMapType::const_iterator const_iterator;
|
||||
|
@ -132,7 +132,7 @@ public:
|
|||
else return "Immediate Dominators Construction";
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function *F) {
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
IDoms.clear(); // Reset from the last time we were run...
|
||||
DominatorSet *DS;
|
||||
if (isPostDominator())
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
else return "Dominator Tree Construction";
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function *F) {
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
reset();
|
||||
DominatorSet *DS;
|
||||
if (isPostDominator())
|
||||
|
@ -289,7 +289,7 @@ public:
|
|||
else return "Dominance Frontier Construction";
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function *) {
|
||||
virtual bool runOnFunction(Function &) {
|
||||
Frontiers.clear();
|
||||
DominatorTree *DT;
|
||||
if (isPostDominator())
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
// values of various types. If they are deemed to be 'unsafe' note that the
|
||||
// type is not safe to transform.
|
||||
//
|
||||
virtual bool run(Module *M);
|
||||
virtual bool run(Module &M);
|
||||
|
||||
// printResults - Loop over the results of the analysis, printing out unsafe
|
||||
// types.
|
||||
|
|
|
@ -51,7 +51,7 @@ private:
|
|||
public:
|
||||
// run - This incorporates all types used by the specified module
|
||||
//
|
||||
bool run(Module *M);
|
||||
bool run(Module &M);
|
||||
|
||||
// getAnalysisUsage - Of course, we provide ourself...
|
||||
//
|
||||
|
|
|
@ -162,22 +162,18 @@ class InstForest : public std::vector<InstTreeNode<Payload> *> {
|
|||
public:
|
||||
// ctor - Create an instruction forest for the specified method...
|
||||
InstForest(Function *F) {
|
||||
for (Function::iterator MI = F->begin(), ME = F->end(); MI != ME; ++MI) {
|
||||
BasicBlock *BB = *MI;
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||
Instruction *Inst = *I;
|
||||
if (!getInstNode(Inst)) { // Do we already have a tree for this inst?
|
||||
for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB)
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
||||
if (!getInstNode(I)) { // Do we already have a tree for this inst?
|
||||
// No, create one! InstTreeNode ctor automatically adds the
|
||||
// created node into our InstMap
|
||||
push_back(new InstTreeNode<Payload>(*this, Inst, 0));
|
||||
push_back(new InstTreeNode<Payload>(*this, I, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dtor - Free the trees...
|
||||
~InstForest() {
|
||||
for (unsigned i = size(); i > 0; --i)
|
||||
for (unsigned i = size(); i != 0; --i)
|
||||
delete operator[](i-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
IntervalIterator() {} // End iterator, empty stack
|
||||
IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
|
||||
OrigContainer = M;
|
||||
if (!ProcessInterval(M->front())) {
|
||||
if (!ProcessInterval(&M->front())) {
|
||||
assert(0 && "ProcessInterval should never fail for first interval!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
const char *getPassName() const { return "Interval Partition Construction"; }
|
||||
|
||||
// run - Calculate the interval partition for this function
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
// IntervalPartition ctor - Build a reduced interval partition from an
|
||||
// existing interval graph. This takes an additional boolean parameter to
|
||||
|
|
|
@ -79,16 +79,16 @@ public:
|
|||
// getLoopFor - Return the inner most loop that BB lives in. If a basic block
|
||||
// is in no loop (for example the entry node), null is returned.
|
||||
//
|
||||
const Loop *getLoopFor(BasicBlock *BB) const {
|
||||
std::map<BasicBlock *, Loop*>::const_iterator I = BBMap.find(BB);
|
||||
const Loop *getLoopFor(const BasicBlock *BB) const {
|
||||
std::map<BasicBlock *, Loop*>::const_iterator I=BBMap.find((BasicBlock*)BB);
|
||||
return I != BBMap.end() ? I->second : 0;
|
||||
}
|
||||
inline const Loop *operator[](BasicBlock *BB) const {
|
||||
inline const Loop *operator[](const BasicBlock *BB) const {
|
||||
return getLoopFor(BB);
|
||||
}
|
||||
|
||||
// getLoopDepth - Return the loop nesting level of the specified block...
|
||||
unsigned getLoopDepth(BasicBlock *BB) const {
|
||||
unsigned getLoopDepth(const BasicBlock *BB) const {
|
||||
const Loop *L = getLoopFor(BB);
|
||||
return L ? L->getLoopDepth() : 0;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
#endif
|
||||
|
||||
// runOnFunction - Pass framework implementation
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
virtual void releaseMemory();
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ Pass *createVerifierPass();
|
|||
// verifyModule - Check a module for errors, printing messages on stderr.
|
||||
// Return true if the module is corrupt.
|
||||
//
|
||||
bool verifyModule(const Module *M);
|
||||
bool verifyModule(const Module &M);
|
||||
|
||||
// verifyFunction - Check a function for errors, useful for use when debugging a
|
||||
// pass.
|
||||
bool verifyFunction(const Function *F);
|
||||
bool verifyFunction(const Function &F);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,8 +29,8 @@ public:
|
|||
if (DeleteStream) delete Out;
|
||||
}
|
||||
|
||||
bool run(Module *M) {
|
||||
(*Out) << M;
|
||||
bool run(Module &M) {
|
||||
(*Out) << (Value&)M;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,8 @@ public:
|
|||
// runOnFunction - This pass just prints a banner followed by the function as
|
||||
// it's processed.
|
||||
//
|
||||
bool runOnFunction(Function *F) {
|
||||
(*Out) << Banner << (Value*)F;
|
||||
bool runOnFunction(Function &F) {
|
||||
(*Out) << Banner << (Value&)F;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,11 +209,11 @@ template <> struct GraphTraits<Inverse<const BasicBlock*> > {
|
|||
// except that the root node is implicitly the first node of the function.
|
||||
//
|
||||
template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
|
||||
static NodeType *getEntryNode(Function *F) { return F->getEntryNode(); }
|
||||
static NodeType *getEntryNode(Function *F) { return &F->getEntryNode(); }
|
||||
};
|
||||
template <> struct GraphTraits<const Function*> :
|
||||
public GraphTraits<const BasicBlock*> {
|
||||
static NodeType *getEntryNode(const Function *F) { return F->getEntryNode(); }
|
||||
static NodeType *getEntryNode(const Function *F) { return &F->getEntryNode();}
|
||||
};
|
||||
|
||||
|
||||
|
@ -225,13 +225,13 @@ template <> struct GraphTraits<const Function*> :
|
|||
template <> struct GraphTraits<Inverse<Function*> > :
|
||||
public GraphTraits<Inverse<BasicBlock*> > {
|
||||
static NodeType *getEntryNode(Inverse<Function*> G) {
|
||||
return G.Graph->front();
|
||||
return &G.Graph->getEntryNode();
|
||||
}
|
||||
};
|
||||
template <> struct GraphTraits<Inverse<const Function*> > :
|
||||
public GraphTraits<Inverse<const BasicBlock*> > {
|
||||
static NodeType *getEntryNode(Inverse<const Function *> G) {
|
||||
return G.Graph->front();
|
||||
return &G.Graph->getEntryNode();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -35,22 +35,22 @@ public:
|
|||
typedef IIty reference;
|
||||
|
||||
template<class M> InstIterator(M &m)
|
||||
: BBs(m.getBasicBlocks()), BB(BBs.begin()) { // begin ctor
|
||||
: BBs(m.getBasicBlockList()), BB(BBs.begin()) { // begin ctor
|
||||
if (BB != BBs.end()) {
|
||||
BI = (*BB)->begin();
|
||||
BI = BB->begin();
|
||||
advanceToNextBB();
|
||||
}
|
||||
}
|
||||
|
||||
template<class M> InstIterator(M &m, bool)
|
||||
: BBs(m.getBasicBlocks()), BB(BBs.end()) { // end ctor
|
||||
: BBs(m.getBasicBlockList()), BB(BBs.end()) { // end ctor
|
||||
}
|
||||
|
||||
// Accessors to get at the underlying iterators...
|
||||
inline BBIty &getBasicBlockIterator() { return BB; }
|
||||
inline BIty &getInstructionIterator() { return BI; }
|
||||
|
||||
inline IIty operator*() const { return *BI; }
|
||||
inline IIty operator*() const { return &*BI; }
|
||||
inline IIty operator->() const { return operator*(); }
|
||||
|
||||
inline bool operator==(const InstIterator &y) const {
|
||||
|
@ -70,9 +70,9 @@ public:
|
|||
}
|
||||
|
||||
InstIterator& operator--() {
|
||||
while (BB == BBs.end() || BI == (*BB)->begin()) {
|
||||
while (BB == BBs.end() || BI == BB->begin()) {
|
||||
--BB;
|
||||
BI = (*BB)->end();
|
||||
BI = BB->end();
|
||||
}
|
||||
--BI;
|
||||
return *this;
|
||||
|
@ -87,19 +87,19 @@ private:
|
|||
inline void advanceToNextBB() {
|
||||
// The only way that the II could be broken is if it is now pointing to
|
||||
// the end() of the current BasicBlock and there are successor BBs.
|
||||
while (BI == (*BB)->end()) {
|
||||
while (BI == BB->end()) {
|
||||
++BB;
|
||||
if (BB == BBs.end()) break;
|
||||
BI = (*BB)->begin();
|
||||
BI = BB->begin();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef InstIterator<ValueHolder<BasicBlock, Function, Function>,
|
||||
typedef InstIterator<iplist<BasicBlock>,
|
||||
Function::iterator, BasicBlock::iterator,
|
||||
Instruction*> inst_iterator;
|
||||
typedef InstIterator<const ValueHolder<BasicBlock, Function, Function>,
|
||||
typedef InstIterator<const iplist<BasicBlock>,
|
||||
Function::const_iterator,
|
||||
BasicBlock::const_iterator,
|
||||
const Instruction*> const_inst_iterator;
|
||||
|
@ -112,5 +112,13 @@ inline const_inst_iterator inst_begin(const Function *F) {
|
|||
inline const_inst_iterator inst_end(const Function *F) {
|
||||
return const_inst_iterator(*F, true);
|
||||
}
|
||||
inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
|
||||
inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
|
||||
inline const_inst_iterator inst_begin(const Function &F) {
|
||||
return const_inst_iterator(F);
|
||||
}
|
||||
inline const_inst_iterator inst_end(const Function &F) {
|
||||
return const_inst_iterator(F, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,7 @@ class AllocationInst; class MemAccessInst;
|
|||
|
||||
|
||||
#define DELEGATE(CLASS_TO_VISIT) \
|
||||
return ((SubClass*)this)->visit##CLASS_TO_VISIT((CLASS_TO_VISIT*)I)
|
||||
return ((SubClass*)this)->visit##CLASS_TO_VISIT((CLASS_TO_VISIT&)I)
|
||||
|
||||
|
||||
template<typename SubClass, typename RetTy=void>
|
||||
|
@ -78,26 +78,32 @@ struct InstVisitor {
|
|||
|
||||
// Define visitors for modules, functions and basic blocks...
|
||||
//
|
||||
void visit(Module *M) {
|
||||
void visit(Module &M) {
|
||||
((SubClass*)this)->visitModule(M);
|
||||
visit(M->begin(), M->end());
|
||||
visit(M.begin(), M.end());
|
||||
}
|
||||
void visit(Function *F) {
|
||||
void visit(Function &F) {
|
||||
((SubClass*)this)->visitFunction(F);
|
||||
visit(F->begin(), F->end());
|
||||
visit(F.begin(), F.end());
|
||||
}
|
||||
void visit(BasicBlock *BB) {
|
||||
void visit(BasicBlock &BB) {
|
||||
((SubClass*)this)->visitBasicBlock(BB);
|
||||
visit(BB->begin(), BB->end());
|
||||
visit(BB.begin(), BB.end());
|
||||
}
|
||||
|
||||
// Forwarding functions so that the user can visit with pointers AND refs.
|
||||
void visit(Module *M) { visit(*M); }
|
||||
void visit(Function *F) { visit(*F); }
|
||||
void visit(BasicBlock *BB) { visit(*BB); }
|
||||
RetTy visit(Instruction *I) { return visit(*I); }
|
||||
|
||||
// visit - Finally, code to visit an instruction...
|
||||
//
|
||||
RetTy visit(Instruction *I) {
|
||||
switch (I->getOpcode()) {
|
||||
RetTy visit(Instruction &I) {
|
||||
switch (I.getOpcode()) {
|
||||
// Build the switch statement using the Instruction.def file...
|
||||
#define HANDLE_INST(NUM, OPCODE, CLASS) \
|
||||
case Instruction::OPCODE:return ((SubClass*)this)->visit##OPCODE((CLASS*)I);
|
||||
case Instruction::OPCODE:return ((SubClass*)this)->visit##OPCODE((CLASS&)I);
|
||||
#include "llvm/Instruction.def"
|
||||
|
||||
default: assert(0 && "Unknown instruction type encountered!");
|
||||
|
@ -116,9 +122,9 @@ struct InstVisitor {
|
|||
// When visiting a module, function or basic block directly, these methods get
|
||||
// called to indicate when transitioning into a new unit.
|
||||
//
|
||||
void visitModule (Module *M) {}
|
||||
void visitFunction (Function *F) {}
|
||||
void visitBasicBlock(BasicBlock *BB) {}
|
||||
void visitModule (Module &M) {}
|
||||
void visitFunction (Function &F) {}
|
||||
void visitBasicBlock(BasicBlock &BB) {}
|
||||
|
||||
|
||||
// Define instruction specific visitor functions that can be overridden to
|
||||
|
@ -133,49 +139,49 @@ struct InstVisitor {
|
|||
// this, we do not autoexpand "Other" instructions, we do it manually.
|
||||
//
|
||||
#define HANDLE_INST(NUM, OPCODE, CLASS) \
|
||||
RetTy visit##OPCODE(CLASS *I) { DELEGATE(CLASS); }
|
||||
RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
|
||||
#define HANDLE_OTHER_INST(NUM, OPCODE, CLASS) // Ignore "other" instructions
|
||||
#include "llvm/Instruction.def"
|
||||
|
||||
// Implement all "other" instructions, except for PHINode
|
||||
RetTy visitCast(CastInst *I) { DELEGATE(CastInst); }
|
||||
RetTy visitCall(CallInst *I) { DELEGATE(CallInst); }
|
||||
RetTy visitShr(ShiftInst *I) { DELEGATE(ShiftInst); }
|
||||
RetTy visitShl(ShiftInst *I) { DELEGATE(ShiftInst); }
|
||||
RetTy visitUserOp1(Instruction *I) { DELEGATE(Instruction); }
|
||||
RetTy visitUserOp2(Instruction *I) { DELEGATE(Instruction); }
|
||||
RetTy visitCast(CastInst &I) { DELEGATE(CastInst); }
|
||||
RetTy visitCall(CallInst &I) { DELEGATE(CallInst); }
|
||||
RetTy visitShr(ShiftInst &I) { DELEGATE(ShiftInst); }
|
||||
RetTy visitShl(ShiftInst &I) { DELEGATE(ShiftInst); }
|
||||
RetTy visitUserOp1(Instruction &I) { DELEGATE(Instruction); }
|
||||
RetTy visitUserOp2(Instruction &I) { DELEGATE(Instruction); }
|
||||
|
||||
|
||||
// Specific Instruction type classes... note that all of the casts are
|
||||
// neccesary because we use the instruction classes as opaque types...
|
||||
//
|
||||
RetTy visitReturnInst(ReturnInst *I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitBranchInst(BranchInst *I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitSwitchInst(SwitchInst *I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitInvokeInst(InvokeInst *I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitGenericUnaryInst(GenericUnaryInst *I) { DELEGATE(UnaryOperator); }
|
||||
RetTy visitGenericBinaryInst(GenericBinaryInst *I){ DELEGATE(BinaryOperator);}
|
||||
RetTy visitSetCondInst(SetCondInst *I) { DELEGATE(BinaryOperator);}
|
||||
RetTy visitMallocInst(MallocInst *I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitAllocaInst(AllocaInst *I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitFreeInst(FreeInst *I) { DELEGATE(Instruction); }
|
||||
RetTy visitLoadInst(LoadInst *I) { DELEGATE(MemAccessInst); }
|
||||
RetTy visitStoreInst(StoreInst *I) { DELEGATE(MemAccessInst); }
|
||||
RetTy visitGetElementPtrInst(GetElementPtrInst *I){ DELEGATE(MemAccessInst); }
|
||||
RetTy visitPHINode(PHINode *I) { DELEGATE(Instruction); }
|
||||
RetTy visitCastInst(CastInst *I) { DELEGATE(Instruction); }
|
||||
RetTy visitCallInst(CallInst *I) { DELEGATE(Instruction); }
|
||||
RetTy visitShiftInst(ShiftInst *I) { DELEGATE(Instruction); }
|
||||
RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
|
||||
RetTy visitGenericUnaryInst(GenericUnaryInst &I) { DELEGATE(UnaryOperator); }
|
||||
RetTy visitGenericBinaryInst(GenericBinaryInst &I){ DELEGATE(BinaryOperator);}
|
||||
RetTy visitSetCondInst(SetCondInst &I) { DELEGATE(BinaryOperator);}
|
||||
RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
|
||||
RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitLoadInst(LoadInst &I) { DELEGATE(MemAccessInst); }
|
||||
RetTy visitStoreInst(StoreInst &I) { DELEGATE(MemAccessInst); }
|
||||
RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(MemAccessInst); }
|
||||
RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); }
|
||||
RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitShiftInst(ShiftInst &I) { DELEGATE(Instruction); }
|
||||
|
||||
// Next level propogators... if the user does not overload a specific
|
||||
// instruction type, they can overload one of these to get the whole class
|
||||
// of instructions...
|
||||
//
|
||||
RetTy visitTerminatorInst(TerminatorInst *I) { DELEGATE(Instruction); }
|
||||
RetTy visitUnaryOperator (UnaryOperator *I) { DELEGATE(Instruction); }
|
||||
RetTy visitBinaryOperator(BinaryOperator *I) { DELEGATE(Instruction); }
|
||||
RetTy visitAllocationInst(AllocationInst *I) { DELEGATE(Instruction); }
|
||||
RetTy visitMemAccessInst (MemAccessInst *I) { DELEGATE(Instruction); }
|
||||
RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitUnaryOperator (UnaryOperator &I) { DELEGATE(Instruction); }
|
||||
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
|
||||
RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); }
|
||||
RetTy visitMemAccessInst (MemAccessInst &I) { DELEGATE(Instruction); }
|
||||
|
||||
// If the user wants a 'default' case, they can choose to override this
|
||||
// function. If this function is not overloaded in the users subclass, then
|
||||
|
@ -183,7 +189,7 @@ struct InstVisitor {
|
|||
//
|
||||
// Note that you MUST override this function if your return type is not void.
|
||||
//
|
||||
void visitInstruction(Instruction *I) {} // Ignore unhandled instructions
|
||||
void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
|
||||
};
|
||||
|
||||
#undef DELEGATE
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
}
|
||||
|
||||
// run - do the transformation
|
||||
virtual bool run(Module *M);
|
||||
virtual bool run(Module &M);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -76,7 +76,7 @@ private:
|
|||
// functions for functions than need to be copied because they have a new
|
||||
// signature type.
|
||||
//
|
||||
void processGlobals(Module *M);
|
||||
void processGlobals(Module &M);
|
||||
|
||||
// transformFunction - This transforms the instructions of the function to use
|
||||
// the new types.
|
||||
|
@ -86,7 +86,7 @@ private:
|
|||
// removeDeadGlobals - This removes the old versions of functions that are no
|
||||
// longer needed.
|
||||
//
|
||||
void removeDeadGlobals(Module *M);
|
||||
void removeDeadGlobals(Module &M);
|
||||
|
||||
private:
|
||||
// ConvertType - Convert from the old type system to the new one...
|
||||
|
|
|
@ -95,31 +95,30 @@ void CallGraph::addToCallGraph(Function *M) {
|
|||
}
|
||||
|
||||
// Look for an indirect method call...
|
||||
for (Function::iterator BBI = M->begin(), BBE = M->end(); BBI != BBE; ++BBI) {
|
||||
BasicBlock *BB = *BBI;
|
||||
for (Function::iterator BB = M->begin(), BBE = M->end(); BB != BBE; ++BB)
|
||||
for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II){
|
||||
Instruction *I = *II;
|
||||
Instruction &I = *II;
|
||||
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I)) {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
|
||||
if (CI->getCalledFunction() == 0)
|
||||
Node->addCalledMethod(ExternalNode);
|
||||
} else if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
|
||||
} else if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
|
||||
if (II->getCalledFunction() == 0)
|
||||
Node->addCalledMethod(ExternalNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CallGraph::run(Module *TheModule) {
|
||||
bool CallGraph::run(Module &M) {
|
||||
destroy();
|
||||
|
||||
Mod = TheModule;
|
||||
Mod = &M;
|
||||
ExternalNode = getNodeFor(0);
|
||||
Root = 0;
|
||||
|
||||
// Add every method to the call graph...
|
||||
for_each(Mod->begin(), Mod->end(), bind_obj(this,&CallGraph::addToCallGraph));
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
||||
addToCallGraph(I);
|
||||
|
||||
// If we didn't find a main method, use the external call graph node
|
||||
if (Root == 0) Root = ExternalNode;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "llvm/Analysis/FindUnsafePointerTypes.h"
|
||||
#include "llvm/Assembly/CachedWriter.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/InstIterator.h"
|
||||
#include "Support/CommandLine.h"
|
||||
|
@ -50,21 +49,20 @@ static inline bool isSafeInstruction(const Instruction *I) {
|
|||
}
|
||||
|
||||
|
||||
bool FindUnsafePointerTypes::run(Module *Mod) {
|
||||
for (Module::iterator MI = Mod->begin(), ME = Mod->end();
|
||||
MI != ME; ++MI) {
|
||||
const Function *M = *MI; // We don't need/want write access
|
||||
for (const_inst_iterator I = inst_begin(M), E = inst_end(M); I != E; ++I) {
|
||||
const Instruction *Inst = *I;
|
||||
const Type *ITy = Inst->getType();
|
||||
bool FindUnsafePointerTypes::run(Module &Mod) {
|
||||
for (Module::iterator FI = Mod.begin(), E = Mod.end();
|
||||
FI != E; ++FI) {
|
||||
const Function *F = FI; // We don't need/want write access
|
||||
for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
|
||||
const Type *ITy = I->getType();
|
||||
if (isa<PointerType>(ITy) && !UnsafeTypes.count((PointerType*)ITy))
|
||||
if (!isSafeInstruction(Inst)) {
|
||||
if (!isSafeInstruction(*I)) {
|
||||
UnsafeTypes.insert((PointerType*)ITy);
|
||||
|
||||
if (PrintFailures) {
|
||||
CachedWriter CW(M->getParent(), std::cerr);
|
||||
CachedWriter CW(F->getParent(), std::cerr);
|
||||
CW << "FindUnsafePointerTypes: Type '" << ITy
|
||||
<< "' marked unsafe in '" << M->getName() << "' by:\n" << Inst;
|
||||
<< "' marked unsafe in '" << F->getName() << "' by:\n" << **I;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
#include "llvm/Analysis/FindUsedTypes.h"
|
||||
#include "llvm/Assembly/CachedWriter.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/Support/InstIterator.h"
|
||||
|
||||
AnalysisID FindUsedTypes::ID(AnalysisID::create<FindUsedTypes>());
|
||||
|
@ -42,25 +40,25 @@ void FindUsedTypes::IncorporateSymbolTable(const SymbolTable *ST) {
|
|||
|
||||
// run - This incorporates all types used by the specified module
|
||||
//
|
||||
bool FindUsedTypes::run(Module *m) {
|
||||
bool FindUsedTypes::run(Module &m) {
|
||||
UsedTypes.clear(); // reset if run multiple times...
|
||||
|
||||
if (IncludeSymbolTables && m->hasSymbolTable())
|
||||
IncorporateSymbolTable(m->getSymbolTable()); // Add symtab first...
|
||||
if (IncludeSymbolTables && m.hasSymbolTable())
|
||||
IncorporateSymbolTable(m.getSymbolTable()); // Add symtab first...
|
||||
|
||||
// Loop over global variables, incorporating their types
|
||||
for (Module::const_giterator I = m->gbegin(), E = m->gend(); I != E; ++I)
|
||||
IncorporateType((*I)->getType());
|
||||
for (Module::const_giterator I = m.gbegin(), E = m.gend(); I != E; ++I)
|
||||
IncorporateType(I->getType());
|
||||
|
||||
for (Module::iterator MI = m->begin(), ME = m->end(); MI != ME; ++MI) {
|
||||
const Function *M = *MI;
|
||||
if (IncludeSymbolTables && M->hasSymbolTable())
|
||||
IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first...
|
||||
for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) {
|
||||
const Function &F = *MI;
|
||||
if (IncludeSymbolTables && F.hasSymbolTable())
|
||||
IncorporateSymbolTable(F.getSymbolTable()); // Add symtab first...
|
||||
|
||||
// Loop over all of the instructions in the function, adding their return
|
||||
// type as well as the types of their operands.
|
||||
//
|
||||
for (const_inst_iterator II = inst_begin(M), IE = inst_end(M);
|
||||
for (const_inst_iterator II = inst_begin(F), IE = inst_end(F);
|
||||
II != IE; ++II) {
|
||||
const Instruction *I = *II;
|
||||
const Type *Ty = I->getType();
|
||||
|
|
|
@ -31,8 +31,8 @@ static bool isLoopInvariant(const Value *V, const Loop *L) {
|
|||
if (isa<Constant>(V) || isa<Argument>(V) || isa<GlobalValue>(V))
|
||||
return true;
|
||||
|
||||
Instruction *I = cast<Instruction>(V);
|
||||
BasicBlock *BB = I->getParent();
|
||||
const Instruction *I = cast<Instruction>(V);
|
||||
const BasicBlock *BB = I->getParent();
|
||||
|
||||
return !L->contains(BB);
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ enum InductionVariable::iType
|
|||
InductionVariable::Classify(const Value *Start, const Value *Step,
|
||||
const Loop *L = 0) {
|
||||
// Check for cannonical and simple linear expressions now...
|
||||
if (ConstantInt *CStart = dyn_cast<ConstantInt>(Start))
|
||||
if (ConstantInt *CStep = dyn_cast<ConstantInt>(Step)) {
|
||||
if (const ConstantInt *CStart = dyn_cast<ConstantInt>(Start))
|
||||
if (const ConstantInt *CStep = dyn_cast<ConstantInt>(Step)) {
|
||||
if (CStart->equalsInt(0) && CStep->equalsInt(1))
|
||||
return Cannonical;
|
||||
else
|
||||
|
|
|
@ -51,19 +51,17 @@ void IntervalPartition::updatePredecessors(Interval *Int) {
|
|||
// IntervalPartition ctor - Build the first level interval partition for the
|
||||
// specified function...
|
||||
//
|
||||
bool IntervalPartition::runOnFunction(Function *F) {
|
||||
assert(F->front() && "Cannot operate on prototypes!");
|
||||
|
||||
bool IntervalPartition::runOnFunction(Function &F) {
|
||||
// Pass false to intervals_begin because we take ownership of it's memory
|
||||
function_interval_iterator I = intervals_begin(F, false);
|
||||
assert(I != intervals_end(F) && "No intervals in function!?!?!");
|
||||
function_interval_iterator I = intervals_begin(&F, false);
|
||||
assert(I != intervals_end(&F) && "No intervals in function!?!?!");
|
||||
|
||||
addIntervalToPartition(RootInterval = *I);
|
||||
|
||||
++I; // After the first one...
|
||||
|
||||
// Add the rest of the intervals to the partition...
|
||||
for_each(I, intervals_end(F),
|
||||
for_each(I, intervals_end(&F),
|
||||
bind_obj(this, &IntervalPartition::addIntervalToPartition));
|
||||
|
||||
// Now that we know all of the successor information, propogate this to the
|
||||
|
|
|
@ -35,7 +35,7 @@ void LoopInfo::releaseMemory() {
|
|||
//===----------------------------------------------------------------------===//
|
||||
// LoopInfo implementation
|
||||
//
|
||||
bool LoopInfo::runOnFunction(Function *F) {
|
||||
bool LoopInfo::runOnFunction(Function &) {
|
||||
releaseMemory();
|
||||
Calculate(getAnalysis<DominatorSet>()); // Update
|
||||
return false;
|
||||
|
|
|
@ -21,7 +21,7 @@ using std::set;
|
|||
AnalysisID DominatorSet::ID(AnalysisID::create<DominatorSet>(), true);
|
||||
AnalysisID DominatorSet::PostDomID(AnalysisID::create<DominatorSet>(), true);
|
||||
|
||||
bool DominatorSet::runOnFunction(Function *F) {
|
||||
bool DominatorSet::runOnFunction(Function &F) {
|
||||
Doms.clear(); // Reset from the last time we were run...
|
||||
|
||||
if (isPostDominator())
|
||||
|
@ -40,17 +40,17 @@ bool DominatorSet::dominates(Instruction *A, Instruction *B) const {
|
|||
|
||||
// Loop through the basic block until we find A or B.
|
||||
BasicBlock::iterator I = BBA->begin();
|
||||
for (; *I != A && *I != B; ++I) /*empty*/;
|
||||
for (; &*I != A && &*I != B; ++I) /*empty*/;
|
||||
|
||||
// A dominates B if it is found first in the basic block...
|
||||
return *I == A;
|
||||
return &*I == A;
|
||||
}
|
||||
|
||||
// calcForwardDominatorSet - This method calculates the forward dominator sets
|
||||
// for the specified function.
|
||||
//
|
||||
void DominatorSet::calcForwardDominatorSet(Function *M) {
|
||||
Root = M->getEntryNode();
|
||||
void DominatorSet::calcForwardDominatorSet(Function &F) {
|
||||
Root = &F.getEntryNode();
|
||||
assert(pred_begin(Root) == pred_end(Root) &&
|
||||
"Root node has predecessors in function!");
|
||||
|
||||
|
@ -59,7 +59,7 @@ void DominatorSet::calcForwardDominatorSet(Function *M) {
|
|||
Changed = false;
|
||||
|
||||
DomSetType WorkingSet;
|
||||
df_iterator<Function*> It = df_begin(M), End = df_end(M);
|
||||
df_iterator<Function*> It = df_begin(&F), End = df_end(&F);
|
||||
for ( ; It != End; ++It) {
|
||||
BasicBlock *BB = *It;
|
||||
pred_iterator PI = pred_begin(BB), PEnd = pred_end(BB);
|
||||
|
@ -93,7 +93,7 @@ void DominatorSet::calcForwardDominatorSet(Function *M) {
|
|||
// only have a single exit node (return stmt), then calculates the post
|
||||
// dominance sets for the function.
|
||||
//
|
||||
void DominatorSet::calcPostDominatorSet(Function *F) {
|
||||
void DominatorSet::calcPostDominatorSet(Function &F) {
|
||||
// Since we require that the unify all exit nodes pass has been run, we know
|
||||
// that there can be at most one return instruction in the function left.
|
||||
// Get it.
|
||||
|
@ -101,8 +101,8 @@ void DominatorSet::calcPostDominatorSet(Function *F) {
|
|||
Root = getAnalysis<UnifyFunctionExitNodes>().getExitNode();
|
||||
|
||||
if (Root == 0) { // No exit node for the function? Postdomsets are all empty
|
||||
for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
|
||||
Doms[*FI] = DomSetType();
|
||||
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
|
||||
Doms[FI] = DomSetType();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ Module *ParseAssemblyFile(const string &Filename) { // throw (ParseException)
|
|||
fclose(F);
|
||||
|
||||
if (Result) { // Check to see that it is valid...
|
||||
if (verifyModule(Result)) {
|
||||
if (verifyModule(*Result)) {
|
||||
delete Result;
|
||||
throw ParseException(Filename, "Source file is not well formed LLVM!");
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ string CurFilename;
|
|||
#define UR_OUT(X)
|
||||
#endif
|
||||
|
||||
// This contains info used when building the body of a method. It is destroyed
|
||||
// when the method is completed.
|
||||
// This contains info used when building the body of a function. It is
|
||||
// destroyed when the function is completed.
|
||||
//
|
||||
typedef vector<Value *> ValueList; // Numbered defs
|
||||
static void ResolveDefinitions(vector<ValueList> &LateResolvers,
|
||||
|
@ -68,9 +68,9 @@ static struct PerModuleInfo {
|
|||
GlobalRefsType GlobalRefs;
|
||||
|
||||
void ModuleDone() {
|
||||
// If we could not resolve some methods at method compilation time (calls to
|
||||
// methods before they are defined), resolve them now... Types are resolved
|
||||
// when the constant pool has been completely parsed.
|
||||
// If we could not resolve some functions at function compilation time
|
||||
// (calls to functions before they are defined), resolve them now... Types
|
||||
// are resolved when the constant pool has been completely parsed.
|
||||
//
|
||||
ResolveDefinitions(LateResolveValues);
|
||||
|
||||
|
@ -88,7 +88,7 @@ static struct PerModuleInfo {
|
|||
ThrowException(UndefinedReferences);
|
||||
}
|
||||
|
||||
Values.clear(); // Clear out method local definitions
|
||||
Values.clear(); // Clear out function local definitions
|
||||
Types.clear();
|
||||
CurrentModule = 0;
|
||||
}
|
||||
|
@ -132,13 +132,13 @@ static struct PerModuleInfo {
|
|||
} CurModule;
|
||||
|
||||
static struct PerFunctionInfo {
|
||||
Function *CurrentFunction; // Pointer to current method being created
|
||||
Function *CurrentFunction; // Pointer to current function being created
|
||||
|
||||
vector<ValueList> Values; // Keep track of numbered definitions
|
||||
vector<ValueList> LateResolveValues;
|
||||
vector<PATypeHolder> Types;
|
||||
map<ValID, PATypeHolder> LateResolveTypes;
|
||||
bool isDeclare; // Is this method a forward declararation?
|
||||
bool isDeclare; // Is this function a forward declararation?
|
||||
|
||||
inline PerFunctionInfo() {
|
||||
CurrentFunction = 0;
|
||||
|
@ -156,12 +156,12 @@ static struct PerFunctionInfo {
|
|||
// resolve the branches now...
|
||||
ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
|
||||
|
||||
Values.clear(); // Clear out method local definitions
|
||||
Values.clear(); // Clear out function local definitions
|
||||
Types.clear();
|
||||
CurrentFunction = 0;
|
||||
isDeclare = false;
|
||||
}
|
||||
} CurMeth; // Info for the current method...
|
||||
} CurMeth; // Info for the current function...
|
||||
|
||||
static bool inFunctionScope() { return CurMeth.CurrentFunction != 0; }
|
||||
|
||||
|
@ -210,7 +210,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
|
|||
Value *N = SymTab ? SymTab->lookup(Type::TypeTy, Name) : 0;
|
||||
|
||||
if (N == 0) {
|
||||
// Symbol table doesn't automatically chain yet... because the method
|
||||
// Symbol table doesn't automatically chain yet... because the function
|
||||
// hasn't been added to the module...
|
||||
//
|
||||
SymTab = CurModule.CurrentModule->getSymbolTable();
|
||||
|
@ -741,7 +741,7 @@ OptInternal : INTERNAL { $$ = true; } | /*empty*/ { $$ = false; };
|
|||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Types includes all predefined types... except void, because it can only be
|
||||
// used in specific contexts (method returning void for example). To have
|
||||
// used in specific contexts (function returning void for example). To have
|
||||
// access to it, a user must explicitly use TypesV.
|
||||
//
|
||||
|
||||
|
@ -810,7 +810,7 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference
|
|||
delete $1;
|
||||
};
|
||||
|
||||
// TypeList - Used for struct declarations and as a basis for method type
|
||||
// TypeList - Used for struct declarations and as a basis for function type
|
||||
// declaration type lists
|
||||
//
|
||||
TypeListI : UpRTypes {
|
||||
|
@ -821,7 +821,7 @@ TypeListI : UpRTypes {
|
|||
($$=$1)->push_back(*$3); delete $3;
|
||||
};
|
||||
|
||||
// ArgTypeList - List of types for a method type declaration...
|
||||
// ArgTypeList - List of types for a function type declaration...
|
||||
ArgTypeListI : TypeListI
|
||||
| TypeListI ',' DOTDOTDOT {
|
||||
($$=$1)->push_back(Type::VoidTy);
|
||||
|
@ -1011,7 +1011,7 @@ Module : FunctionList {
|
|||
CurModule.ModuleDone();
|
||||
};
|
||||
|
||||
// FunctionList - A list of methods, preceeded by a constant pool.
|
||||
// FunctionList - A list of functions, preceeded by a constant pool.
|
||||
//
|
||||
FunctionList : FunctionList Function {
|
||||
$$ = $1;
|
||||
|
@ -1164,10 +1164,11 @@ FunctionHeaderH : OptInternal TypesV FuncName '(' ArgList ')' {
|
|||
// Yes it is. If this is the case, either we need to be a forward decl,
|
||||
// or it needs to be.
|
||||
if (!CurMeth.isDeclare && !M->isExternal())
|
||||
ThrowException("Redefinition of method '" + FunctionName + "'!");
|
||||
ThrowException("Redefinition of function '" + FunctionName + "'!");
|
||||
|
||||
// If we found a preexisting method prototype, remove it from the module,
|
||||
// so that we don't get spurious conflicts with global & local variables.
|
||||
// If we found a preexisting function prototype, remove it from the
|
||||
// module, so that we don't get spurious conflicts with global & local
|
||||
// variables.
|
||||
//
|
||||
CurModule.CurrentModule->getFunctionList().remove(M);
|
||||
}
|
||||
|
@ -1182,10 +1183,8 @@ FunctionHeaderH : OptInternal TypesV FuncName '(' ArgList ')' {
|
|||
|
||||
CurMeth.FunctionStart(M);
|
||||
|
||||
// Add all of the arguments we parsed to the method...
|
||||
// Add all of the arguments we parsed to the function...
|
||||
if ($5 && !CurMeth.isDeclare) { // Is null if empty...
|
||||
Function::ArgumentListType &ArgList = M->getArgumentList();
|
||||
|
||||
for (list<pair<Argument*, char*> >::iterator I = $5->begin();
|
||||
I != $5->end(); ++I) {
|
||||
if (setValueName(I->first, I->second)) { // Insert into symtab...
|
||||
|
@ -1193,7 +1192,7 @@ FunctionHeaderH : OptInternal TypesV FuncName '(' ArgList ')' {
|
|||
}
|
||||
|
||||
InsertValue(I->first);
|
||||
ArgList.push_back(I->first);
|
||||
M->getArgumentList().push_back(I->first);
|
||||
}
|
||||
delete $5; // We're now done with the argument list
|
||||
} else if ($5) {
|
||||
|
@ -1212,7 +1211,7 @@ BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function
|
|||
FunctionHeader : FunctionHeaderH BEGIN {
|
||||
$$ = CurMeth.CurrentFunction;
|
||||
|
||||
// Resolve circular types before we parse the body of the method.
|
||||
// Resolve circular types before we parse the body of the function.
|
||||
ResolveTypes(CurMeth.LateResolveTypes);
|
||||
};
|
||||
|
||||
|
@ -1275,10 +1274,10 @@ ResolvedVal : Types ValueRef {
|
|||
|
||||
|
||||
BasicBlockList : BasicBlockList BasicBlock {
|
||||
($$ = $1)->getBasicBlocks().push_back($2);
|
||||
($$ = $1)->getBasicBlockList().push_back($2);
|
||||
}
|
||||
| FunctionHeader BasicBlock { // Do not allow methods with 0 basic blocks
|
||||
($$ = $1)->getBasicBlocks().push_back($2);
|
||||
| FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks
|
||||
($$ = $1)->getBasicBlockList().push_back($2);
|
||||
};
|
||||
|
||||
|
||||
|
@ -1358,7 +1357,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||
}
|
||||
delete $2;
|
||||
|
||||
Value *V = getVal(PMTy, $3); // Get the method we're calling...
|
||||
Value *V = getVal(PMTy, $3); // Get the function we're calling...
|
||||
|
||||
BasicBlock *Normal = dyn_cast<BasicBlock>($8);
|
||||
BasicBlock *Except = dyn_cast<BasicBlock>($10);
|
||||
|
@ -1494,7 +1493,7 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
|
|||
}
|
||||
delete $2;
|
||||
|
||||
Value *V = getVal(PMTy, $3); // Get the method we're calling...
|
||||
Value *V = getVal(PMTy, $3); // Get the function we're calling...
|
||||
|
||||
// Create the call node...
|
||||
if (!$5) { // Has no arguments?
|
||||
|
|
|
@ -1489,18 +1489,17 @@ namespace {
|
|||
AU.addRequired(FunctionLiveVarInfo::ID);
|
||||
}
|
||||
|
||||
bool runOnFunction(Function *F);
|
||||
bool runOnFunction(Function &F);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
bool
|
||||
InstructionSchedulingWithSSA::runOnFunction(Function *M)
|
||||
bool InstructionSchedulingWithSSA::runOnFunction(Function &F)
|
||||
{
|
||||
if (SchedDebugLevel == Sched_Disable)
|
||||
return false;
|
||||
|
||||
SchedGraphSet graphSet(M, target);
|
||||
SchedGraphSet graphSet(&F, target);
|
||||
|
||||
if (SchedDebugLevel >= Sched_PrintSchedGraphs)
|
||||
{
|
||||
|
@ -1520,7 +1519,7 @@ InstructionSchedulingWithSSA::runOnFunction(Function *M)
|
|||
cerr << "\n*** TRACE OF INSTRUCTION SCHEDULING OPERATIONS\n\n";
|
||||
|
||||
// expensive!
|
||||
SchedPriorities schedPrio(M, graph,getAnalysis<FunctionLiveVarInfo>());
|
||||
SchedPriorities schedPrio(&F, graph,getAnalysis<FunctionLiveVarInfo>());
|
||||
SchedulingManager S(target, graph, schedPrio);
|
||||
|
||||
ChooseInstructionsForDelaySlots(S, bb, graph); // modifies graph
|
||||
|
@ -1533,7 +1532,7 @@ InstructionSchedulingWithSSA::runOnFunction(Function *M)
|
|||
if (SchedDebugLevel >= Sched_PrintMachineCode)
|
||||
{
|
||||
cerr << "\n*** Machine instructions after INSTRUCTION SCHEDULING\n";
|
||||
MachineCodeForMethod::get(M).dump();
|
||||
MachineCodeForMethod::get(&F).dump();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -985,7 +985,7 @@ SchedGraphSet::buildGraphsForMethod(const Function *F,
|
|||
const TargetMachine& target)
|
||||
{
|
||||
for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI)
|
||||
addGraph(new SchedGraph(*BI, target));
|
||||
addGraph(new SchedGraph(BI, target));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,29 +84,20 @@ void LiveRangeInfo::constructLiveRanges() {
|
|||
|
||||
// first find the live ranges for all incoming args of the function since
|
||||
// those LRs start from the start of the function
|
||||
|
||||
// get the argument list
|
||||
const Function::ArgumentListType& ArgList = Meth->getArgumentList();
|
||||
|
||||
Function::ArgumentListType::const_iterator ArgIt = ArgList.begin();
|
||||
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
|
||||
LiveRange * ArgRange = new LiveRange(); // creates a new LR and
|
||||
const Value *Val = (const Value *) *ArgIt;
|
||||
|
||||
ArgRange->insert(Val); // add the arg (def) to it
|
||||
LiveRangeMap[Val] = ArgRange;
|
||||
for (Function::const_aiterator AI = Meth->abegin(); AI != Meth->aend(); ++AI){
|
||||
LiveRange *ArgRange = new LiveRange(); // creates a new LR and
|
||||
ArgRange->insert(AI); // add the arg (def) to it
|
||||
LiveRangeMap[AI] = ArgRange;
|
||||
|
||||
// create a temp machine op to find the register class of value
|
||||
//const MachineOperand Op(MachineOperand::MO_VirtualRegister);
|
||||
|
||||
unsigned rcid = MRI.getRegClassIDOfValue( Val );
|
||||
ArgRange->setRegClass(RegClassList[ rcid ] );
|
||||
unsigned rcid = MRI.getRegClassIDOfValue(AI);
|
||||
ArgRange->setRegClass(RegClassList[rcid]);
|
||||
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cerr << " adding LiveRange for argument "
|
||||
<< RAV((const Value *)*ArgIt) << "\n";
|
||||
}
|
||||
if( DEBUG_RA > 1)
|
||||
cerr << " adding LiveRange for argument " << RAV(AI) << "\n";
|
||||
}
|
||||
|
||||
// Now suggest hardware registers for these function args
|
||||
|
@ -123,7 +114,7 @@ void LiveRangeInfo::constructLiveRanges() {
|
|||
// the same Value in machine instructions.
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
const MachineCodeForBasicBlock& MIVec = BBI->getMachineInstrVec();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for(MachineCodeForBasicBlock::const_iterator MInstIterator = MIVec.begin();
|
||||
|
@ -275,7 +266,7 @@ void LiveRangeInfo::coalesceLRs()
|
|||
BBI != BBE; ++BBI) {
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
const MachineCodeForBasicBlock& MIVec = BBI->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
|
|
|
@ -49,12 +49,11 @@ namespace {
|
|||
|
||||
const char *getPassName() const { return "Register Allocation"; }
|
||||
|
||||
bool runOnFunction(Function *F) {
|
||||
bool runOnFunction(Function &F) {
|
||||
if (DEBUG_RA)
|
||||
cerr << "\n******************** Function "<< F->getName()
|
||||
<< " ********************\n";
|
||||
cerr << "\n********* Function "<< F.getName() << " ***********\n";
|
||||
|
||||
PhyRegAlloc PRA(F, Target, &getAnalysis<FunctionLiveVarInfo>(),
|
||||
PhyRegAlloc PRA(&F, Target, &getAnalysis<FunctionLiveVarInfo>(),
|
||||
&getAnalysis<LoopInfo>());
|
||||
PRA.allocateRegisters();
|
||||
|
||||
|
@ -87,7 +86,7 @@ PhyRegAlloc::PhyRegAlloc(Function *F, const TargetMachine& tm,
|
|||
|
||||
// create each RegisterClass and put in RegClassList
|
||||
//
|
||||
for(unsigned int rc=0; rc < NumOfRegClasses; rc++)
|
||||
for (unsigned rc=0; rc < NumOfRegClasses; rc++)
|
||||
RegClassList.push_back(new RegClass(F, MRI.getMachineRegClass(rc),
|
||||
&ResColList));
|
||||
}
|
||||
|
@ -97,7 +96,7 @@ PhyRegAlloc::PhyRegAlloc(Function *F, const TargetMachine& tm,
|
|||
// Destructor: Deletes register classes
|
||||
//----------------------------------------------------------------------------
|
||||
PhyRegAlloc::~PhyRegAlloc() {
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses; rc++)
|
||||
for ( unsigned rc=0; rc < NumOfRegClasses; rc++)
|
||||
delete RegClassList[rc];
|
||||
|
||||
AddedInstrMap.clear();
|
||||
|
@ -120,7 +119,7 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
|
|||
if (HMI->first) {
|
||||
LiveRange *L = HMI->second; // get the LiveRange
|
||||
if (!L) {
|
||||
if( DEBUG_RA) {
|
||||
if (DEBUG_RA) {
|
||||
cerr << "\n*?!?Warning: Null liver range found for: "
|
||||
<< RAV(HMI->first) << "\n";
|
||||
}
|
||||
|
@ -128,7 +127,7 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
|
|||
}
|
||||
// if the Value * is not null, and LR
|
||||
// is not yet written to the IGNodeList
|
||||
if( !(L->getUserIGNode()) ) {
|
||||
if (!(L->getUserIGNode()) ) {
|
||||
RegClass *const RC = // RegClass of first value in the LR
|
||||
RegClassList[ L->getRegClass()->getID() ];
|
||||
|
||||
|
@ -138,10 +137,10 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
|
|||
}
|
||||
|
||||
// init RegClassList
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[rc]->createInterferenceGraph();
|
||||
|
||||
if( DEBUG_RA)
|
||||
if (DEBUG_RA)
|
||||
cerr << "LRLists Created!\n";
|
||||
}
|
||||
|
||||
|
@ -171,7 +170,7 @@ void PhyRegAlloc::addInterference(const Value *Def,
|
|||
|
||||
// for each live var in live variable set
|
||||
//
|
||||
for( ; LIt != LVSet->end(); ++LIt) {
|
||||
for ( ; LIt != LVSet->end(); ++LIt) {
|
||||
|
||||
if (DEBUG_RA > 1)
|
||||
cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> ";
|
||||
|
@ -184,7 +183,7 @@ void PhyRegAlloc::addInterference(const Value *Def,
|
|||
// doesn't have a dominating def - see Assumptions above
|
||||
//
|
||||
if (LROfVar) {
|
||||
if(LROfDef == LROfVar) // do not set interf for same LR
|
||||
if (LROfDef == LROfVar) // do not set interf for same LR
|
||||
continue;
|
||||
|
||||
// if 2 reg classes are the same set interference
|
||||
|
@ -212,20 +211,20 @@ void PhyRegAlloc::addInterference(const Value *Def,
|
|||
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
||||
const ValueSet *LVSetAft) {
|
||||
|
||||
if( DEBUG_RA)
|
||||
if (DEBUG_RA)
|
||||
cerr << "\n For call inst: " << *MInst;
|
||||
|
||||
ValueSet::const_iterator LIt = LVSetAft->begin();
|
||||
|
||||
// for each live var in live variable set after machine inst
|
||||
//
|
||||
for( ; LIt != LVSetAft->end(); ++LIt) {
|
||||
for ( ; LIt != LVSetAft->end(); ++LIt) {
|
||||
|
||||
// get the live range corresponding to live var
|
||||
//
|
||||
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
|
||||
|
||||
if( LR && DEBUG_RA) {
|
||||
if (LR && DEBUG_RA) {
|
||||
cerr << "\n\tLR Aft Call: ";
|
||||
printSet(*LR);
|
||||
}
|
||||
|
@ -233,9 +232,9 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||
// LR can be null if it is a const since a const
|
||||
// doesn't have a dominating def - see Assumptions above
|
||||
//
|
||||
if( LR ) {
|
||||
if (LR ) {
|
||||
LR->setCallInterference();
|
||||
if( DEBUG_RA) {
|
||||
if (DEBUG_RA) {
|
||||
cerr << "\n ++Added call interf for LR: " ;
|
||||
printSet(*LR);
|
||||
}
|
||||
|
@ -259,7 +258,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||
|
||||
// If the CALL is an indirect call, find the LR of the function pointer.
|
||||
// That has a call interference because it conflicts with outgoing args.
|
||||
if( const Value *AddrVal = argDesc->getIndirectFuncPtr()) {
|
||||
if (const Value *AddrVal = argDesc->getIndirectFuncPtr()) {
|
||||
LiveRange *AddrValLR = LRI.getLiveRangeForValue( AddrVal );
|
||||
assert( AddrValLR && "No LR for indirect addr val of call");
|
||||
AddrValLR->setCallInterference();
|
||||
|
@ -278,7 +277,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||
void PhyRegAlloc::buildInterferenceGraphs()
|
||||
{
|
||||
|
||||
if(DEBUG_RA) cerr << "Creating interference graphs ...\n";
|
||||
if (DEBUG_RA) cerr << "Creating interference graphs ...\n";
|
||||
|
||||
unsigned BBLoopDepthCost;
|
||||
for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
|
||||
|
@ -286,26 +285,26 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||
|
||||
// find the 10^(loop_depth) of this BB
|
||||
//
|
||||
BBLoopDepthCost = (unsigned) pow(10.0, LoopDepthCalc->getLoopDepth(*BBI));
|
||||
BBLoopDepthCost = (unsigned)pow(10.0, LoopDepthCalc->getLoopDepth(BBI));
|
||||
|
||||
// get the iterator for machine instructions
|
||||
//
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
const MachineCodeForBasicBlock& MIVec = BBI->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator MII = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
//
|
||||
for( ; MII != MIVec.end(); ++MII) {
|
||||
for ( ; MII != MIVec.end(); ++MII) {
|
||||
|
||||
const MachineInstr *MInst = *MII;
|
||||
|
||||
// get the LV set after the instruction
|
||||
//
|
||||
const ValueSet &LVSetAI = LVI->getLiveVarSetAfterMInst(MInst, *BBI);
|
||||
const ValueSet &LVSetAI = LVI->getLiveVarSetAfterMInst(MInst, BBI);
|
||||
|
||||
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
|
||||
|
||||
if( isCallInst ) {
|
||||
if (isCallInst ) {
|
||||
// set the isCallInterference flag of each live range wich extends
|
||||
// accross this call instruction. This information is used by graph
|
||||
// coloring algo to avoid allocating volatile colors to live ranges
|
||||
|
@ -339,9 +338,9 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||
// instr (currently, only calls have this).
|
||||
//
|
||||
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
|
||||
if( NumOfImpRefs > 0 ) {
|
||||
for(unsigned z=0; z < NumOfImpRefs; z++)
|
||||
if( MInst->implicitRefIsDefined(z) )
|
||||
if ( NumOfImpRefs > 0 ) {
|
||||
for (unsigned z=0; z < NumOfImpRefs; z++)
|
||||
if (MInst->implicitRefIsDefined(z) )
|
||||
addInterference( MInst->getImplicitRef(z), &LVSetAI, isCallInst );
|
||||
}
|
||||
|
||||
|
@ -355,7 +354,7 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||
//
|
||||
addInterferencesForArgs();
|
||||
|
||||
if( DEBUG_RA)
|
||||
if (DEBUG_RA)
|
||||
cerr << "Interference graphs calculted!\n";
|
||||
|
||||
}
|
||||
|
@ -380,14 +379,14 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||
assert((LROfOp1 || !It1.isDef()) && "No LR for Def in PSEUDO insruction");
|
||||
|
||||
MachineInstr::const_val_op_iterator It2 = It1;
|
||||
for(++It2; It2 != ItE; ++It2) {
|
||||
for (++It2; It2 != ItE; ++It2) {
|
||||
const LiveRange *LROfOp2 = LRI.getLiveRangeForValue(*It2);
|
||||
|
||||
if (LROfOp2) {
|
||||
RegClass *RCOfOp1 = LROfOp1->getRegClass();
|
||||
RegClass *RCOfOp2 = LROfOp2->getRegClass();
|
||||
|
||||
if( RCOfOp1 == RCOfOp2 ){
|
||||
if (RCOfOp1 == RCOfOp2 ){
|
||||
RCOfOp1->setInterference( LROfOp1, LROfOp2 );
|
||||
setInterf = true;
|
||||
}
|
||||
|
@ -409,21 +408,14 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||
//----------------------------------------------------------------------------
|
||||
void PhyRegAlloc::addInterferencesForArgs() {
|
||||
// get the InSet of root BB
|
||||
const ValueSet &InSet = LVI->getInSetOfBB(Meth->front());
|
||||
const ValueSet &InSet = LVI->getInSetOfBB(&Meth->front());
|
||||
|
||||
// get the argument list
|
||||
const Function::ArgumentListType &ArgList = Meth->getArgumentList();
|
||||
|
||||
// get an iterator to arg list
|
||||
Function::ArgumentListType::const_iterator ArgIt = ArgList.begin();
|
||||
|
||||
|
||||
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
|
||||
addInterference((Value*)*ArgIt, &InSet, false);// add interferences between
|
||||
// args and LVars at start
|
||||
if( DEBUG_RA > 1)
|
||||
cerr << " - %% adding interference for argument "
|
||||
<< RAV((const Value *)*ArgIt) << "\n";
|
||||
for (Function::const_aiterator AI = Meth->abegin(); AI != Meth->aend(); ++AI) {
|
||||
// add interferences between args and LVars at start
|
||||
addInterference(AI, &InSet, false);
|
||||
|
||||
if (DEBUG_RA > 1)
|
||||
cerr << " - %% adding interference for argument " << RAV(AI) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,9 +464,9 @@ AppendInstructions(std::vector<MachineInstr *> &IAft,
|
|||
{
|
||||
MachineInstr* OrigMI = *MII;
|
||||
std::vector<MachineInstr *>::iterator AdIt;
|
||||
for( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt )
|
||||
for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt )
|
||||
{
|
||||
if(DEBUG_RA) {
|
||||
if (DEBUG_RA) {
|
||||
if (OrigMI) cerr << "For MInst: " << *OrigMI;
|
||||
cerr << msg << " APPENDed instr: " << **AdIt << "\n";
|
||||
}
|
||||
|
@ -487,25 +479,22 @@ AppendInstructions(std::vector<MachineInstr *> &IAft,
|
|||
|
||||
void PhyRegAlloc::updateMachineCode()
|
||||
{
|
||||
const BasicBlock* entryBB = Meth->getEntryNode();
|
||||
if (entryBB) {
|
||||
MachineCodeForBasicBlock& MIVec = entryBB->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::iterator MII = MIVec.begin();
|
||||
MachineCodeForBasicBlock& MIVec = Meth->getEntryNode().getMachineInstrVec();
|
||||
|
||||
// Insert any instructions needed at method entry
|
||||
PrependInstructions(AddedInstrAtEntry.InstrnsBefore, MIVec, MII,
|
||||
"At function entry: \n");
|
||||
assert(AddedInstrAtEntry.InstrnsAfter.empty() &&
|
||||
"InstrsAfter should be unnecessary since we are just inserting at "
|
||||
"the function entry point here.");
|
||||
}
|
||||
// Insert any instructions needed at method entry
|
||||
MachineCodeForBasicBlock::iterator MII = MIVec.begin();
|
||||
PrependInstructions(AddedInstrAtEntry.InstrnsBefore, MIVec, MII,
|
||||
"At function entry: \n");
|
||||
assert(AddedInstrAtEntry.InstrnsAfter.empty() &&
|
||||
"InstrsAfter should be unnecessary since we are just inserting at "
|
||||
"the function entry point here.");
|
||||
|
||||
for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
|
||||
BBI != BBE; ++BBI) {
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
for(MachineCodeForBasicBlock::iterator MII = MIVec.begin();
|
||||
MachineCodeForBasicBlock &MIVec = BBI->getMachineInstrVec();
|
||||
for (MachineCodeForBasicBlock::iterator MII = MIVec.begin();
|
||||
MII != MIVec.end(); ++MII) {
|
||||
|
||||
MachineInstr *MInst = *MII;
|
||||
|
@ -530,7 +519,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
mcInfo.popAllTempValues(TM);
|
||||
|
||||
if (TM.getInstrInfo().isCall(Opcode))
|
||||
MRI.colorCallArgs(MInst, LRI, &AI, *this, *BBI);
|
||||
MRI.colorCallArgs(MInst, LRI, &AI, *this, BBI);
|
||||
else if (TM.getInstrInfo().isReturn(Opcode))
|
||||
MRI.colorRetValue(MInst, LRI, &AI);
|
||||
}
|
||||
|
@ -540,7 +529,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
|
||||
// if this machine instr is call, insert caller saving code
|
||||
|
||||
if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
|
||||
if ((TM.getInstrInfo()).isCall( MInst->getOpCode()) )
|
||||
MRI.insertCallerSavingCode(MInst, *BBI, *this );
|
||||
|
||||
*/
|
||||
|
@ -551,22 +540,22 @@ void PhyRegAlloc::updateMachineCode()
|
|||
// mcInfo.popAllTempValues(TM);
|
||||
// TODO ** : do later
|
||||
|
||||
//for(MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
|
||||
//for (MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
|
||||
|
||||
|
||||
// Now replace set the registers for operands in the machine instruction
|
||||
//
|
||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
|
||||
MachineOperand& Op = MInst->getOperand(OpNum);
|
||||
|
||||
if( Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
if (Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
Op.getOperandType() == MachineOperand::MO_CCRegister) {
|
||||
|
||||
const Value *const Val = Op.getVRegValue();
|
||||
|
||||
// delete this condition checking later (must assert if Val is null)
|
||||
if( !Val) {
|
||||
if (!Val) {
|
||||
if (DEBUG_RA)
|
||||
cerr << "Warning: NULL Value found for operand\n";
|
||||
continue;
|
||||
|
@ -575,7 +564,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
|
||||
LiveRange *const LR = LRI.getLiveRangeForValue(Val);
|
||||
|
||||
if ( !LR ) {
|
||||
if (!LR ) {
|
||||
|
||||
// nothing to worry if it's a const or a label
|
||||
|
||||
|
@ -586,7 +575,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
}
|
||||
|
||||
// if register is not allocated, mark register as invalid
|
||||
if( Op.getAllocatedRegNum() == -1)
|
||||
if (Op.getAllocatedRegNum() == -1)
|
||||
Op.setRegForValue( MRI.getInvalidRegNum());
|
||||
|
||||
|
||||
|
@ -595,7 +584,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
|
||||
unsigned RCID = (LR->getRegClass())->getID();
|
||||
|
||||
if( LR->hasColor() ) {
|
||||
if (LR->hasColor() ) {
|
||||
Op.setRegForValue( MRI.getUnifiedRegNum(RCID, LR->getColor()) );
|
||||
}
|
||||
else {
|
||||
|
@ -604,7 +593,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
// for spilled opeands in this machine instruction
|
||||
|
||||
//assert(0 && "LR must be spilled");
|
||||
insertCode4SpilledLR(LR, MInst, *BBI, OpNum );
|
||||
insertCode4SpilledLR(LR, MInst, BBI, OpNum );
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -620,7 +609,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
// If there are instructions to be added, *before* this machine
|
||||
// instruction, add them now.
|
||||
//
|
||||
if(AddedInstrMap.count(MInst)) {
|
||||
if (AddedInstrMap.count(MInst)) {
|
||||
PrependInstructions(AddedInstrMap[MInst].InstrnsBefore, MIVec, MII,"");
|
||||
}
|
||||
|
||||
|
@ -638,7 +627,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||
if ((delay=TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) >0){
|
||||
move2DelayedInstr(MInst, *(MII+delay) );
|
||||
|
||||
if(DEBUG_RA) cerr<< "\nMoved an added instr after the delay slot";
|
||||
if (DEBUG_RA) cerr<< "\nMoved an added instr after the delay slot";
|
||||
}
|
||||
|
||||
else {
|
||||
|
@ -698,10 +687,10 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
|
|||
AI.InstrnsBefore.insert(AI.InstrnsBefore.end(),
|
||||
AdIMid.begin(), AdIMid.end());
|
||||
|
||||
if(MIBef)
|
||||
if (MIBef)
|
||||
AI.InstrnsBefore.push_back(MIBef);
|
||||
|
||||
if(MIAft)
|
||||
if (MIAft)
|
||||
AI.InstrnsAfter.insert(AI.InstrnsAfter.begin(), MIAft);
|
||||
|
||||
} else { // if this is a Def
|
||||
|
@ -722,14 +711,16 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
|
|||
|
||||
} // if !DEF
|
||||
|
||||
cerr << "\nFor Inst " << *MInst;
|
||||
cerr << " - SPILLED LR: "; printSet(*LR);
|
||||
cerr << "\n - Added Instructions:";
|
||||
if (MIBef) cerr << *MIBef;
|
||||
for (vector<MachineInstr*>::const_iterator II=AdIMid.begin();
|
||||
II != AdIMid.end(); ++II)
|
||||
cerr << **II;
|
||||
if (MIAft) cerr << *MIAft;
|
||||
if (DEBUG_RA) {
|
||||
cerr << "\nFor Inst " << *MInst;
|
||||
cerr << " - SPILLED LR: "; printSet(*LR);
|
||||
cerr << "\n - Added Instructions:";
|
||||
if (MIBef) cerr << *MIBef;
|
||||
for (vector<MachineInstr*>::const_iterator II=AdIMid.begin();
|
||||
II != AdIMid.end(); ++II)
|
||||
cerr << **II;
|
||||
if (MIAft) cerr << *MIAft;
|
||||
}
|
||||
|
||||
Op.setRegForValue(TmpRegU); // set the opearnd
|
||||
}
|
||||
|
@ -755,7 +746,7 @@ int PhyRegAlloc::getUsableUniRegAtMI(RegClass *RC,
|
|||
int RegU = getUnusedUniRegAtMI(RC, MInst, LVSetBef);
|
||||
|
||||
|
||||
if( RegU != -1) {
|
||||
if (RegU != -1) {
|
||||
// we found an unused register, so we can simply use it
|
||||
MIBef = MIAft = NULL;
|
||||
}
|
||||
|
@ -799,20 +790,20 @@ int PhyRegAlloc::getUnusedUniRegAtMI(RegClass *RC,
|
|||
|
||||
std::vector<bool> &IsColorUsedArr = RC->getIsColorUsedArr();
|
||||
|
||||
for(unsigned i=0; i < NumAvailRegs; i++) // Reset array
|
||||
for (unsigned i=0; i < NumAvailRegs; i++) // Reset array
|
||||
IsColorUsedArr[i] = false;
|
||||
|
||||
ValueSet::const_iterator LIt = LVSetBef->begin();
|
||||
|
||||
// for each live var in live variable set after machine inst
|
||||
for( ; LIt != LVSetBef->end(); ++LIt) {
|
||||
for ( ; LIt != LVSetBef->end(); ++LIt) {
|
||||
|
||||
// get the live range corresponding to live var
|
||||
LiveRange *const LRofLV = LRI.getLiveRangeForValue(*LIt );
|
||||
|
||||
// LR can be null if it is a const since a const
|
||||
// doesn't have a dominating def - see Assumptions above
|
||||
if( LRofLV && LRofLV->getRegClass() == RC && LRofLV->hasColor() )
|
||||
if (LRofLV && LRofLV->getRegClass() == RC && LRofLV->hasColor() )
|
||||
IsColorUsedArr[ LRofLV->getColor() ] = true;
|
||||
}
|
||||
|
||||
|
@ -822,7 +813,7 @@ int PhyRegAlloc::getUnusedUniRegAtMI(RegClass *RC,
|
|||
|
||||
setRelRegsUsedByThisInst(RC, MInst);
|
||||
|
||||
for(unsigned c=0; c < NumAvailRegs; c++) // find first unused color
|
||||
for (unsigned c=0; c < NumAvailRegs; c++) // find first unused color
|
||||
if (!IsColorUsedArr[c])
|
||||
return MRI.getUnifiedRegNum(RC->getID(), c);
|
||||
|
||||
|
@ -841,12 +832,12 @@ int PhyRegAlloc::getUniRegNotUsedByThisInst(RegClass *RC,
|
|||
unsigned NumAvailRegs = RC->getNumOfAvailRegs();
|
||||
|
||||
|
||||
for(unsigned i=0; i < NumAvailRegs ; i++) // Reset array
|
||||
for (unsigned i=0; i < NumAvailRegs ; i++) // Reset array
|
||||
IsColorUsedArr[i] = false;
|
||||
|
||||
setRelRegsUsedByThisInst(RC, MInst);
|
||||
|
||||
for(unsigned c=0; c < RC->getNumOfAvailRegs(); c++)// find first unused color
|
||||
for (unsigned c=0; c < RC->getNumOfAvailRegs(); c++)// find first unused color
|
||||
if (!IsColorUsedArr[c])
|
||||
return MRI.getUnifiedRegNum(RC->getID(), c);
|
||||
|
||||
|
@ -865,19 +856,19 @@ void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC,
|
|||
|
||||
vector<bool> &IsColorUsedArr = RC->getIsColorUsedArr();
|
||||
|
||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
|
||||
const MachineOperand& Op = MInst->getOperand(OpNum);
|
||||
|
||||
if( Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
if (Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
Op.getOperandType() == MachineOperand::MO_CCRegister ) {
|
||||
|
||||
const Value *const Val = Op.getVRegValue();
|
||||
|
||||
if( Val )
|
||||
if( MRI.getRegClassIDOfValue(Val) == RC->getID() ) {
|
||||
if (Val )
|
||||
if (MRI.getRegClassIDOfValue(Val) == RC->getID() ) {
|
||||
int Reg;
|
||||
if( (Reg=Op.getAllocatedRegNum()) != -1) {
|
||||
if ((Reg=Op.getAllocatedRegNum()) != -1) {
|
||||
IsColorUsedArr[Reg] = true;
|
||||
}
|
||||
else {
|
||||
|
@ -885,8 +876,8 @@ void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC,
|
|||
// a register but it has a LR and that received a color
|
||||
|
||||
LiveRange *LROfVal = LRI.getLiveRangeForValue(Val);
|
||||
if( LROfVal)
|
||||
if( LROfVal->hasColor() )
|
||||
if (LROfVal)
|
||||
if (LROfVal->hasColor() )
|
||||
IsColorUsedArr[LROfVal->getColor()] = true;
|
||||
}
|
||||
|
||||
|
@ -900,12 +891,12 @@ void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC,
|
|||
|
||||
// If there are implicit references, mark them as well
|
||||
|
||||
for(unsigned z=0; z < MInst->getNumImplicitRefs(); z++) {
|
||||
for (unsigned z=0; z < MInst->getNumImplicitRefs(); z++) {
|
||||
|
||||
LiveRange *const LRofImpRef =
|
||||
LRI.getLiveRangeForValue( MInst->getImplicitRef(z) );
|
||||
|
||||
if(LRofImpRef && LRofImpRef->hasColor())
|
||||
if (LRofImpRef && LRofImpRef->hasColor())
|
||||
IsColorUsedArr[LRofImpRef->getColor()] = true;
|
||||
}
|
||||
}
|
||||
|
@ -957,35 +948,35 @@ void PhyRegAlloc::printMachineCode()
|
|||
|
||||
for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
|
||||
BBI != BBE; ++BBI) {
|
||||
cerr << "\n"; printLabel(*BBI); cerr << ": ";
|
||||
cerr << "\n"; printLabel(BBI); cerr << ": ";
|
||||
|
||||
// get the iterator for machine instructions
|
||||
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock& MIVec = BBI->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::iterator MII = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MII != MIVec.end(); ++MII) {
|
||||
for ( ; MII != MIVec.end(); ++MII) {
|
||||
MachineInstr *const MInst = *MII;
|
||||
|
||||
cerr << "\n\t";
|
||||
cerr << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
|
||||
|
||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
for (unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
MachineOperand& Op = MInst->getOperand(OpNum);
|
||||
|
||||
if( Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
if (Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
Op.getOperandType() == MachineOperand::MO_CCRegister /*||
|
||||
Op.getOperandType() == MachineOperand::MO_PCRelativeDisp*/ ) {
|
||||
|
||||
const Value *const Val = Op.getVRegValue () ;
|
||||
// ****this code is temporary till NULL Values are fixed
|
||||
if( ! Val ) {
|
||||
if (! Val ) {
|
||||
cerr << "\t<*NULL*>";
|
||||
continue;
|
||||
}
|
||||
|
||||
// if a label or a constant
|
||||
if(isa<BasicBlock>(Val)) {
|
||||
if (isa<BasicBlock>(Val)) {
|
||||
cerr << "\t"; printLabel( Op.getVRegValue () );
|
||||
} else {
|
||||
// else it must be a register value
|
||||
|
@ -997,17 +988,17 @@ void PhyRegAlloc::printMachineCode()
|
|||
else
|
||||
cerr << "(" << Val << ")";
|
||||
|
||||
if( Op.opIsDef() )
|
||||
if (Op.opIsDef() )
|
||||
cerr << "*";
|
||||
|
||||
const LiveRange *LROfVal = LRI.getLiveRangeForValue(Val);
|
||||
if( LROfVal )
|
||||
if( LROfVal->hasSpillOffset() )
|
||||
if (LROfVal )
|
||||
if (LROfVal->hasSpillOffset() )
|
||||
cerr << "$";
|
||||
}
|
||||
|
||||
}
|
||||
else if(Op.getOperandType() == MachineOperand::MO_MachineRegister) {
|
||||
else if (Op.getOperandType() == MachineOperand::MO_MachineRegister) {
|
||||
cerr << "\t" << "%" << MRI.getUnifiedRegName(Op.getMachineRegNum());
|
||||
}
|
||||
|
||||
|
@ -1018,10 +1009,10 @@ void PhyRegAlloc::printMachineCode()
|
|||
|
||||
|
||||
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
|
||||
if( NumOfImpRefs > 0) {
|
||||
if (NumOfImpRefs > 0) {
|
||||
cerr << "\tImplicit:";
|
||||
|
||||
for(unsigned z=0; z < NumOfImpRefs; z++)
|
||||
for (unsigned z=0; z < NumOfImpRefs; z++)
|
||||
cerr << RAV(MInst->getImplicitRef(z)) << "\t";
|
||||
}
|
||||
|
||||
|
@ -1047,7 +1038,7 @@ void PhyRegAlloc::colorCallRetArgs()
|
|||
CallRetInstrListType &CallRetInstList = LRI.getCallRetInstrList();
|
||||
CallRetInstrListType::const_iterator It = CallRetInstList.begin();
|
||||
|
||||
for( ; It != CallRetInstList.end(); ++It ) {
|
||||
for ( ; It != CallRetInstList.end(); ++It ) {
|
||||
|
||||
const MachineInstr *const CRMI = *It;
|
||||
unsigned OpCode = CRMI->getOpCode();
|
||||
|
@ -1076,8 +1067,8 @@ void PhyRegAlloc::colorCallRetArgs()
|
|||
//----------------------------------------------------------------------------
|
||||
void PhyRegAlloc::colorIncomingArgs()
|
||||
{
|
||||
const BasicBlock *const FirstBB = Meth->front();
|
||||
const MachineInstr *FirstMI = FirstBB->getMachineInstrVec().front();
|
||||
const BasicBlock &FirstBB = Meth->front();
|
||||
const MachineInstr *FirstMI = FirstBB.getMachineInstrVec().front();
|
||||
assert(FirstMI && "No machine instruction in entry BB");
|
||||
|
||||
MRI.colorMethodArgs(Meth, LRI, &AddedInstrAtEntry);
|
||||
|
@ -1104,19 +1095,19 @@ void PhyRegAlloc::printLabel(const Value *const Val) {
|
|||
|
||||
void PhyRegAlloc::markUnusableSugColors()
|
||||
{
|
||||
if(DEBUG_RA ) cerr << "\nmarking unusable suggested colors ...\n";
|
||||
if (DEBUG_RA ) cerr << "\nmarking unusable suggested colors ...\n";
|
||||
|
||||
// hash map iterator
|
||||
LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();
|
||||
LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();
|
||||
|
||||
for(; HMI != HMIEnd ; ++HMI ) {
|
||||
for (; HMI != HMIEnd ; ++HMI ) {
|
||||
if (HMI->first) {
|
||||
LiveRange *L = HMI->second; // get the LiveRange
|
||||
if (L) {
|
||||
if(L->hasSuggestedColor()) {
|
||||
if (L->hasSuggestedColor()) {
|
||||
int RCID = L->getRegClass()->getID();
|
||||
if( MRI.isRegVolatile( RCID, L->getSuggestedColor()) &&
|
||||
if (MRI.isRegVolatile( RCID, L->getSuggestedColor()) &&
|
||||
L->isCallInterference() )
|
||||
L->setSuggestedColorUsable( false );
|
||||
else
|
||||
|
@ -1142,7 +1133,7 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs() {
|
|||
LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin();
|
||||
LiveRangeMapType::const_iterator HMIEnd = LRI.getLiveRangeMap()->end();
|
||||
|
||||
for( ; HMI != HMIEnd ; ++HMI) {
|
||||
for ( ; HMI != HMIEnd ; ++HMI) {
|
||||
if (HMI->first && HMI->second) {
|
||||
LiveRange *L = HMI->second; // get the LiveRange
|
||||
if (!L->hasColor()) // NOTE: ** allocating the size of long Type **
|
||||
|
@ -1176,25 +1167,25 @@ void PhyRegAlloc::allocateRegisters()
|
|||
|
||||
if (DEBUG_RA) {
|
||||
// print all LRs in all reg classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIGNodeList();
|
||||
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[rc]->printIGNodeList();
|
||||
|
||||
// print IGs in all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIG();
|
||||
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[rc]->printIG();
|
||||
}
|
||||
|
||||
|
||||
LRI.coalesceLRs(); // coalesce all live ranges
|
||||
|
||||
|
||||
if( DEBUG_RA) {
|
||||
if (DEBUG_RA) {
|
||||
// print all LRs in all reg classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIGNodeList();
|
||||
|
||||
// print IGs in all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIG();
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1197,7 @@ void PhyRegAlloc::allocateRegisters()
|
|||
markUnusableSugColors();
|
||||
|
||||
// color all register classes using the graph coloring algo
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
for (unsigned rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->colorAllRegs();
|
||||
|
||||
// Atter grpah coloring, if some LRs did not receive a color (i.e, spilled)
|
||||
|
|
|
@ -31,7 +31,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
static bool AllIndicesZero(const MemAccessInst *MAI) {
|
||||
for (User::const_op_iterator S = MAI->idx_begin(), E = MAI->idx_end();
|
||||
S != E; ++S)
|
||||
if (!isa<Constant>(*S) || !cast<Constant>(*S)->isNullValue())
|
||||
if (!isa<Constant>(S->get()) || !cast<Constant>(S->get())->isNullValue())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
|
|||
unsigned Scale = (unsigned)ScaleVal * OldTypeSize / DataSize;
|
||||
|
||||
// Locate the malloc instruction, because we may be inserting instructions
|
||||
It = find(BB->getInstList().begin(), BB->getInstList().end(), MI);
|
||||
It = MI;
|
||||
|
||||
// If we have a scale, apply it first...
|
||||
if (Expr.Var) {
|
||||
|
@ -118,7 +118,7 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
|
|||
if (Expr.Var->getType() != Type::UIntTy) {
|
||||
Instruction *CI = new CastInst(Expr.Var, Type::UIntTy);
|
||||
if (Expr.Var->hasName()) CI->setName(Expr.Var->getName()+"-uint");
|
||||
It = BB->getInstList().insert(It, CI)+1;
|
||||
It = ++BB->getInstList().insert(It, CI);
|
||||
Expr.Var = CI;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
|
|||
BinaryOperator::create(Instruction::Mul, Expr.Var,
|
||||
ConstantUInt::get(Type::UIntTy, Scale));
|
||||
if (Expr.Var->hasName()) ScI->setName(Expr.Var->getName()+"-scl");
|
||||
It = BB->getInstList().insert(It, ScI)+1;
|
||||
It = ++BB->getInstList().insert(It, ScI);
|
||||
Expr.Var = ScI;
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
|
|||
BinaryOperator::create(Instruction::Add, Expr.Var,
|
||||
ConstantUInt::get(Type::UIntTy, Offset));
|
||||
if (Expr.Var->hasName()) AddI->setName(Expr.Var->getName()+"-off");
|
||||
It = BB->getInstList().insert(It, AddI)+1;
|
||||
It = ++BB->getInstList().insert(It, AddI);
|
||||
Expr.Var = AddI;
|
||||
}
|
||||
|
||||
|
@ -193,9 +193,10 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty,
|
|||
// We also do not allow conversion of a cast that casts from a ptr to array
|
||||
// of X to a *X. For example: cast [4 x %List *] * %val to %List * *
|
||||
//
|
||||
if (PointerType *SPT = dyn_cast<PointerType>(I->getOperand(0)->getType()))
|
||||
if (PointerType *DPT = dyn_cast<PointerType>(I->getType()))
|
||||
if (ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
|
||||
if (const PointerType *SPT =
|
||||
dyn_cast<PointerType>(I->getOperand(0)->getType()))
|
||||
if (const PointerType *DPT = dyn_cast<PointerType>(I->getType()))
|
||||
if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
|
||||
if (AT->getElementType() == DPT->getElementType())
|
||||
return false;
|
||||
break;
|
||||
|
@ -475,7 +476,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
|
|||
// and we could convert this to an appropriate GEP for the new type.
|
||||
//
|
||||
const PointerType *NewSrcTy = PointerType::get(PVTy);
|
||||
BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
|
||||
BasicBlock::iterator It = I;
|
||||
|
||||
// Check to see if 'N' is an expression that can be converted to
|
||||
// the appropriate size... if so, allow it.
|
||||
|
@ -519,9 +520,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
|
|||
|
||||
assert(Res->getType() == Ty && "Didn't convert expr to correct type!");
|
||||
|
||||
BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
|
||||
assert(It != BIL.end() && "Instruction not in own basic block??");
|
||||
BIL.insert(It, Res);
|
||||
BIL.insert(I, Res);
|
||||
|
||||
// Add the instruction to the expression map
|
||||
VMC.ExprMap[I] = Res;
|
||||
|
@ -618,9 +617,10 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
|
|||
// We also do not allow conversion of a cast that casts from a ptr to array
|
||||
// of X to a *X. For example: cast [4 x %List *] * %val to %List * *
|
||||
//
|
||||
if (PointerType *SPT = dyn_cast<PointerType>(I->getOperand(0)->getType()))
|
||||
if (PointerType *DPT = dyn_cast<PointerType>(I->getType()))
|
||||
if (ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
|
||||
if (const PointerType *SPT =
|
||||
dyn_cast<PointerType>(I->getOperand(0)->getType()))
|
||||
if (const PointerType *DPT = dyn_cast<PointerType>(I->getType()))
|
||||
if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
|
||||
if (AT->getElementType() == DPT->getElementType())
|
||||
return false;
|
||||
return true;
|
||||
|
@ -719,7 +719,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
|
|||
// a whole structure at a time), so the level raiser must be trying to
|
||||
// store into the first field. Check for this and allow it now:
|
||||
//
|
||||
if (StructType *SElTy = dyn_cast<StructType>(ElTy)) {
|
||||
if (const StructType *SElTy = dyn_cast<StructType>(ElTy)) {
|
||||
unsigned Offset = 0;
|
||||
std::vector<Value*> Indices;
|
||||
ElTy = getStructOffsetType(ElTy, Offset, Indices, false);
|
||||
|
@ -817,9 +817,9 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
|
|||
|
||||
// Are we trying to change the function pointer value to a new type?
|
||||
if (OpNum == 0) {
|
||||
PointerType *PTy = dyn_cast<PointerType>(Ty);
|
||||
const PointerType *PTy = dyn_cast<PointerType>(Ty);
|
||||
if (PTy == 0) return false; // Can't convert to a non-pointer type...
|
||||
FunctionType *MTy = dyn_cast<FunctionType>(PTy->getElementType());
|
||||
const FunctionType *MTy = dyn_cast<FunctionType>(PTy->getElementType());
|
||||
if (MTy == 0) return false; // Can't convert to a non ptr to function...
|
||||
|
||||
// Perform sanity checks to make sure that new function type has the
|
||||
|
@ -926,7 +926,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
if (isa<PointerType>(NewTy)) {
|
||||
Value *IndexVal = I->getOperand(OldVal == I->getOperand(0) ? 1 : 0);
|
||||
std::vector<Value*> Indices;
|
||||
BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
|
||||
BasicBlock::iterator It = I;
|
||||
|
||||
if (const Type *ETy = ConvertableToGEP(NewTy, IndexVal, Indices, &It)) {
|
||||
// If successful, convert the add to a GEP
|
||||
|
@ -1016,7 +1016,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
// Convert a one index getelementptr into just about anything that is
|
||||
// desired.
|
||||
//
|
||||
BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
|
||||
BasicBlock::iterator It = I;
|
||||
const Type *OldElTy = cast<PointerType>(I->getType())->getElementType();
|
||||
unsigned DataSize = TD.getTypeSize(OldElTy);
|
||||
Value *Index = I->getOperand(1);
|
||||
|
@ -1025,7 +1025,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
// Insert a multiply of the old element type is not a unit size...
|
||||
Index = BinaryOperator::create(Instruction::Mul, Index,
|
||||
ConstantUInt::get(Type::UIntTy, DataSize));
|
||||
It = BIL.insert(It, cast<Instruction>(Index))+1;
|
||||
It = ++BIL.insert(It, cast<Instruction>(Index));
|
||||
}
|
||||
|
||||
// Perform the conversion now...
|
||||
|
@ -1042,7 +1042,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
// Convert a getelementptr sbyte * %reg111, uint 16 freely back to
|
||||
// anything that is a pointer type...
|
||||
//
|
||||
BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
|
||||
BasicBlock::iterator It = I;
|
||||
|
||||
// Check to see if the second argument is an expression that can
|
||||
// be converted to the appropriate size... if so, allow it.
|
||||
|
@ -1086,8 +1086,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
std::vector<Value*> Params(I->op_begin()+1, I->op_end());
|
||||
|
||||
if (Meth == OldVal) { // Changing the function pointer?
|
||||
PointerType *NewPTy = cast<PointerType>(NewVal->getType());
|
||||
FunctionType *NewTy = cast<FunctionType>(NewPTy->getElementType());
|
||||
const PointerType *NewPTy = cast<PointerType>(NewVal->getType());
|
||||
const FunctionType *NewTy = cast<FunctionType>(NewPTy->getElementType());
|
||||
const FunctionType::ParamTypes &PTs = NewTy->getParamTypes();
|
||||
|
||||
// Get an iterator to the call instruction so that we can insert casts for
|
||||
|
@ -1096,7 +1096,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
// compatible. The reason for this is that we prefer to have resolved
|
||||
// functions but casted arguments if possible.
|
||||
//
|
||||
BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
|
||||
BasicBlock::iterator It = I;
|
||||
|
||||
// Convert over all of the call operands to their new types... but only
|
||||
// convert over the part that is not in the vararg section of the call.
|
||||
|
@ -1107,7 +1107,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
// is a lossless cast...
|
||||
//
|
||||
Params[i] = new CastInst(Params[i], PTs[i], "call.resolve.cast");
|
||||
It = BIL.insert(It, cast<Instruction>(Params[i]))+1;
|
||||
It = ++BIL.insert(It, cast<Instruction>(Params[i]));
|
||||
}
|
||||
Meth = NewVal; // Update call destination to new value
|
||||
|
||||
|
@ -1130,7 +1130,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
|||
// If the instruction was newly created, insert it into the instruction
|
||||
// stream.
|
||||
//
|
||||
BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
|
||||
BasicBlock::iterator It = I;
|
||||
assert(It != BIL.end() && "Instruction not in own basic block??");
|
||||
BIL.insert(It, Res); // Keep It pointing to old instruction
|
||||
|
||||
|
@ -1186,7 +1186,7 @@ static void RecursiveDelete(ValueMapCache &Cache, Instruction *I) {
|
|||
|
||||
for (User::op_iterator OI = I->op_begin(), OE = I->op_end();
|
||||
OI != OE; ++OI)
|
||||
if (Instruction *U = dyn_cast<Instruction>(*OI)) {
|
||||
if (Instruction *U = dyn_cast<Instruction>(OI->get())) {
|
||||
*OI = 0;
|
||||
RecursiveDelete(Cache, U);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#include "llvm/Transforms/CleanupGCCOutput.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
@ -34,7 +32,7 @@ namespace {
|
|||
struct FunctionResolvingPass : public Pass {
|
||||
const char *getPassName() const { return "Resolve Functions"; }
|
||||
|
||||
bool run(Module *M);
|
||||
bool run(Module &M);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -50,12 +48,10 @@ static void ConvertCallTo(CallInst *CI, Function *Dest) {
|
|||
Dest->getFunctionType()->getParamTypes();
|
||||
BasicBlock *BB = CI->getParent();
|
||||
|
||||
// Get an iterator to where we want to insert cast instructions if the
|
||||
// Keep an iterator to where we want to insert cast instructions if the
|
||||
// argument types don't agree.
|
||||
//
|
||||
BasicBlock::iterator BBI = find(BB->begin(), BB->end(), CI);
|
||||
assert(BBI != BB->end() && "CallInst not in parent block?");
|
||||
|
||||
BasicBlock::iterator BBI = CI;
|
||||
assert(CI->getNumOperands()-1 == ParamTys.size() &&
|
||||
"Function calls resolved funny somehow, incompatible number of args");
|
||||
|
||||
|
@ -68,7 +64,7 @@ static void ConvertCallTo(CallInst *CI, Function *Dest) {
|
|||
|
||||
if (V->getType() != ParamTys[i-1]) { // Must insert a cast...
|
||||
Instruction *Cast = new CastInst(V, ParamTys[i-1]);
|
||||
BBI = BB->getInstList().insert(BBI, Cast)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, Cast);
|
||||
V = Cast;
|
||||
}
|
||||
|
||||
|
@ -80,7 +76,7 @@ static void ConvertCallTo(CallInst *CI, Function *Dest) {
|
|||
// Replace the old call instruction with a new call instruction that calls
|
||||
// the real function.
|
||||
//
|
||||
BBI = BB->getInstList().insert(BBI, NewCall)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, NewCall);
|
||||
|
||||
// Remove the old call instruction from the program...
|
||||
BB->getInstList().remove(BBI);
|
||||
|
@ -110,8 +106,8 @@ static void ConvertCallTo(CallInst *CI, Function *Dest) {
|
|||
}
|
||||
|
||||
|
||||
bool FunctionResolvingPass::run(Module *M) {
|
||||
SymbolTable *ST = M->getSymbolTable();
|
||||
bool FunctionResolvingPass::run(Module &M) {
|
||||
SymbolTable *ST = M.getSymbolTable();
|
||||
if (!ST) return false;
|
||||
|
||||
std::map<string, vector<Function*> > Functions;
|
||||
|
@ -151,9 +147,8 @@ bool FunctionResolvingPass::run(Module *M) {
|
|||
// warnings... here we will actually DCE the function so that it isn't
|
||||
// used later.
|
||||
//
|
||||
if (Functions[i]->use_size() == 0) {
|
||||
M->getFunctionList().remove(Functions[i]);
|
||||
delete Functions[i];
|
||||
if (Functions[i]->use_empty()) {
|
||||
M.getFunctionList().erase(Functions[i]);
|
||||
Functions.erase(Functions.begin()+i);
|
||||
Changed = true;
|
||||
++NumResolved;
|
||||
|
|
|
@ -20,18 +20,16 @@
|
|||
|
||||
#include "llvm/Transforms/FunctionInlining.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/iTerminators.h"
|
||||
#include "llvm/iPHINode.h"
|
||||
#include "llvm/iOther.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Argument.h"
|
||||
#include "Support/StatisticReporter.h"
|
||||
|
||||
static Statistic<> NumInlined("inline\t\t- Number of functions inlined");
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
static Statistic<> NumInlined("inline\t\t- Number of functions inlined");
|
||||
using std::cerr;
|
||||
|
||||
// RemapInstruction - Convert the instruction operands from referencing the
|
||||
|
@ -65,17 +63,16 @@ static inline void RemapInstruction(Instruction *I,
|
|||
// exists in the instruction stream. Similiarly this will inline a recursive
|
||||
// function by one level.
|
||||
//
|
||||
bool InlineFunction(BasicBlock::iterator CIIt) {
|
||||
assert(isa<CallInst>(*CIIt) && "InlineFunction only works on CallInst nodes");
|
||||
assert((*CIIt)->getParent() && "Instruction not embedded in basic block!");
|
||||
assert((*CIIt)->getParent()->getParent() && "Instruction not in function!");
|
||||
bool InlineFunction(CallInst *CI) {
|
||||
assert(isa<CallInst>(CI) && "InlineFunction only works on CallInst nodes");
|
||||
assert(CI->getParent() && "Instruction not embedded in basic block!");
|
||||
assert(CI->getParent()->getParent() && "Instruction not in function!");
|
||||
|
||||
CallInst *CI = cast<CallInst>(*CIIt);
|
||||
const Function *CalledMeth = CI->getCalledFunction();
|
||||
if (CalledMeth == 0 || // Can't inline external function or indirect call!
|
||||
CalledMeth->isExternal()) return false;
|
||||
const Function *CalledFunc = CI->getCalledFunction();
|
||||
if (CalledFunc == 0 || // Can't inline external function or indirect call!
|
||||
CalledFunc->isExternal()) return false;
|
||||
|
||||
//cerr << "Inlining " << CalledMeth->getName() << " into "
|
||||
//cerr << "Inlining " << CalledFunc->getName() << " into "
|
||||
// << CurrentMeth->getName() << "\n";
|
||||
|
||||
BasicBlock *OrigBB = CI->getParent();
|
||||
|
@ -84,7 +81,7 @@ bool InlineFunction(BasicBlock::iterator CIIt) {
|
|||
// immediately before the call. The original basic block now ends with an
|
||||
// unconditional branch to NewBB, and NewBB starts with the call instruction.
|
||||
//
|
||||
BasicBlock *NewBB = OrigBB->splitBasicBlock(CIIt);
|
||||
BasicBlock *NewBB = OrigBB->splitBasicBlock(CI);
|
||||
NewBB->setName("InlinedFunctionReturnNode");
|
||||
|
||||
// Remove (unlink) the CallInst from the start of the new basic block.
|
||||
|
@ -95,8 +92,8 @@ bool InlineFunction(BasicBlock::iterator CIIt) {
|
|||
// function.
|
||||
//
|
||||
PHINode *PHI = 0;
|
||||
if (CalledMeth->getReturnType() != Type::VoidTy) {
|
||||
PHI = new PHINode(CalledMeth->getReturnType(), CI->getName());
|
||||
if (CalledFunc->getReturnType() != Type::VoidTy) {
|
||||
PHI = new PHINode(CalledFunc->getReturnType(), CI->getName());
|
||||
|
||||
// The PHI node should go at the front of the new basic block to merge all
|
||||
// possible incoming values.
|
||||
|
@ -118,19 +115,17 @@ bool InlineFunction(BasicBlock::iterator CIIt) {
|
|||
// Add the function arguments to the mapping: (start counting at 1 to skip the
|
||||
// function reference itself)
|
||||
//
|
||||
Function::ArgumentListType::const_iterator PTI =
|
||||
CalledMeth->getArgumentList().begin();
|
||||
Function::const_aiterator PTI = CalledFunc->abegin();
|
||||
for (unsigned a = 1, E = CI->getNumOperands(); a != E; ++a, ++PTI)
|
||||
ValueMap[*PTI] = CI->getOperand(a);
|
||||
ValueMap[PTI] = CI->getOperand(a);
|
||||
|
||||
ValueMap[NewBB] = NewBB; // Returns get converted to reference NewBB
|
||||
|
||||
// Loop over all of the basic blocks in the function, inlining them as
|
||||
// appropriate. Keep track of the first basic block of the function...
|
||||
//
|
||||
for (Function::const_iterator BI = CalledMeth->begin();
|
||||
BI != CalledMeth->end(); ++BI) {
|
||||
const BasicBlock *BB = *BI;
|
||||
for (Function::const_iterator BB = CalledFunc->begin();
|
||||
BB != CalledFunc->end(); ++BB) {
|
||||
assert(BB->getTerminator() && "BasicBlock doesn't have terminator!?!?");
|
||||
|
||||
// Create a new basic block to copy instructions into!
|
||||
|
@ -148,23 +143,24 @@ bool InlineFunction(BasicBlock::iterator CIIt) {
|
|||
// Loop over all instructions copying them over...
|
||||
Instruction *NewInst;
|
||||
for (BasicBlock::const_iterator II = BB->begin();
|
||||
II != (BB->end()-1); ++II) {
|
||||
IBB->getInstList().push_back((NewInst = (*II)->clone()));
|
||||
ValueMap[*II] = NewInst; // Add instruction map to value.
|
||||
if ((*II)->hasName())
|
||||
NewInst->setName((*II)->getName()+".i"); // .i = inlined once
|
||||
II != --BB->end(); ++II) {
|
||||
IBB->getInstList().push_back((NewInst = II->clone()));
|
||||
ValueMap[II] = NewInst; // Add instruction map to value.
|
||||
if (II->hasName())
|
||||
NewInst->setName(II->getName()+".i"); // .i = inlined once
|
||||
}
|
||||
|
||||
// Copy over the terminator now...
|
||||
switch (TI->getOpcode()) {
|
||||
case Instruction::Ret: {
|
||||
const ReturnInst *RI = cast<const ReturnInst>(TI);
|
||||
const ReturnInst *RI = cast<ReturnInst>(TI);
|
||||
|
||||
if (PHI) { // The PHI node should include this value!
|
||||
assert(RI->getReturnValue() && "Ret should have value!");
|
||||
assert(RI->getReturnValue()->getType() == PHI->getType() &&
|
||||
"Ret value not consistent in function!");
|
||||
PHI->addIncoming((Value*)RI->getReturnValue(), cast<BasicBlock>(BB));
|
||||
PHI->addIncoming((Value*)RI->getReturnValue(),
|
||||
(BasicBlock*)cast<BasicBlock>(&*BB));
|
||||
}
|
||||
|
||||
// Add a branch to the code that was after the original Call.
|
||||
|
@ -185,15 +181,14 @@ bool InlineFunction(BasicBlock::iterator CIIt) {
|
|||
// Loop over all of the instructions in the function, fixing up operand
|
||||
// references as we go. This uses ValueMap to do all the hard work.
|
||||
//
|
||||
for (Function::const_iterator BI = CalledMeth->begin();
|
||||
BI != CalledMeth->end(); ++BI) {
|
||||
const BasicBlock *BB = *BI;
|
||||
for (Function::const_iterator BB = CalledFunc->begin();
|
||||
BB != CalledFunc->end(); ++BB) {
|
||||
BasicBlock *NBB = (BasicBlock*)ValueMap[BB];
|
||||
|
||||
// Loop over all instructions, fixing each one as we find it...
|
||||
//
|
||||
for (BasicBlock::iterator II = NBB->begin(); II != NBB->end(); II++)
|
||||
RemapInstruction(*II, ValueMap);
|
||||
for (BasicBlock::iterator II = NBB->begin(); II != NBB->end(); ++II)
|
||||
RemapInstruction(II, ValueMap);
|
||||
}
|
||||
|
||||
if (PHI) RemapInstruction(PHI, ValueMap); // Fix the PHI node also...
|
||||
|
@ -204,24 +199,13 @@ bool InlineFunction(BasicBlock::iterator CIIt) {
|
|||
TerminatorInst *Br = OrigBB->getTerminator();
|
||||
assert(Br && Br->getOpcode() == Instruction::Br &&
|
||||
"splitBasicBlock broken!");
|
||||
Br->setOperand(0, ValueMap[CalledMeth->front()]);
|
||||
Br->setOperand(0, ValueMap[&CalledFunc->front()]);
|
||||
|
||||
// Since we are now done with the CallInst, we can finally delete it.
|
||||
delete CI;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InlineFunction(CallInst *CI) {
|
||||
assert(CI->getParent() && "CallInst not embeded in BasicBlock!");
|
||||
BasicBlock *PBB = CI->getParent();
|
||||
|
||||
BasicBlock::iterator CallIt = find(PBB->begin(), PBB->end(), CI);
|
||||
|
||||
assert(CallIt != PBB->end() &&
|
||||
"CallInst has parent that doesn't contain CallInst?!?");
|
||||
return InlineFunction(CallIt);
|
||||
}
|
||||
|
||||
static inline bool ShouldInlineFunction(const CallInst *CI, const Function *F) {
|
||||
assert(CI->getParent() && CI->getParent()->getParent() &&
|
||||
"Call not embedded into a function!");
|
||||
|
@ -242,11 +226,12 @@ static inline bool ShouldInlineFunction(const CallInst *CI, const Function *F) {
|
|||
|
||||
static inline bool DoFunctionInlining(BasicBlock *BB) {
|
||||
for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(*I)) {
|
||||
if (CallInst *CI = dyn_cast<CallInst>(&*I)) {
|
||||
// Check to see if we should inline this function
|
||||
Function *F = CI->getCalledFunction();
|
||||
if (F && ShouldInlineFunction(CI, F))
|
||||
return InlineFunction(I);
|
||||
if (F && ShouldInlineFunction(CI, F)) {
|
||||
return InlineFunction(CI);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -255,16 +240,14 @@ static inline bool DoFunctionInlining(BasicBlock *BB) {
|
|||
// doFunctionInlining - Use a heuristic based approach to inline functions that
|
||||
// seem to look good.
|
||||
//
|
||||
static bool doFunctionInlining(Function *F) {
|
||||
static bool doFunctionInlining(Function &F) {
|
||||
bool Changed = false;
|
||||
|
||||
// Loop through now and inline instructions a basic block at a time...
|
||||
for (Function::iterator I = F->begin(); I != F->end(); )
|
||||
if (DoFunctionInlining(*I)) {
|
||||
for (Function::iterator I = F.begin(); I != F.end(); )
|
||||
if (DoFunctionInlining(I)) {
|
||||
++NumInlined;
|
||||
Changed = true;
|
||||
// Iterator is now invalidated by new basic blocks inserted
|
||||
I = F->begin();
|
||||
} else {
|
||||
++I;
|
||||
}
|
||||
|
@ -275,7 +258,7 @@ static bool doFunctionInlining(Function *F) {
|
|||
namespace {
|
||||
struct FunctionInlining : public FunctionPass {
|
||||
const char *getPassName() const { return "Function Inlining"; }
|
||||
virtual bool runOnFunction(Function *F) {
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
return doFunctionInlining(F);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -33,12 +33,12 @@ public:
|
|||
// doPassInitialization - For the raise allocations pass, this finds a
|
||||
// declaration for malloc and free if they exist.
|
||||
//
|
||||
bool doInitialization(Module *M);
|
||||
bool doInitialization(Module &M);
|
||||
|
||||
// runOnBasicBlock - This method does the actual work of converting
|
||||
// instructions over, assuming that the pass has already been initialized.
|
||||
//
|
||||
bool runOnBasicBlock(BasicBlock *BB);
|
||||
bool runOnBasicBlock(BasicBlock &BB);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -50,7 +50,7 @@ Pass *createRaiseAllocationsPass() {
|
|||
}
|
||||
|
||||
|
||||
bool RaiseAllocations::doInitialization(Module *M) {
|
||||
bool RaiseAllocations::doInitialization(Module &M) {
|
||||
// If the module has a symbol table, they might be referring to the malloc
|
||||
// and free functions. If this is the case, grab the method pointers that
|
||||
// the module is using.
|
||||
|
@ -68,22 +68,22 @@ bool RaiseAllocations::doInitialization(Module *M) {
|
|||
std::vector<const Type*>(1, PointerType::get(Type::SByteTy)),
|
||||
false);
|
||||
|
||||
MallocFunc = M->getFunction("malloc", MallocType);
|
||||
FreeFunc = M->getFunction("free" , FreeType);
|
||||
MallocFunc = M.getFunction("malloc", MallocType);
|
||||
FreeFunc = M.getFunction("free" , FreeType);
|
||||
|
||||
// Check to see if the prototype is missing, giving us sbyte*(...) * malloc
|
||||
// This handles the common declaration of: 'char *malloc();'
|
||||
if (MallocFunc == 0) {
|
||||
MallocType = FunctionType::get(PointerType::get(Type::SByteTy),
|
||||
std::vector<const Type*>(), true);
|
||||
MallocFunc = M->getFunction("malloc", MallocType);
|
||||
MallocFunc = M.getFunction("malloc", MallocType);
|
||||
}
|
||||
|
||||
// Check to see if the prototype was forgotten, giving us void (...) * free
|
||||
// This handles the common forward declaration of: 'void free();'
|
||||
if (FreeFunc == 0) {
|
||||
FreeType = FunctionType::get(Type::VoidTy, std::vector<const Type*>(),true);
|
||||
FreeFunc = M->getFunction("free", FreeType);
|
||||
FreeFunc = M.getFunction("free", FreeType);
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,12 +95,12 @@ bool RaiseAllocations::doInitialization(Module *M) {
|
|||
|
||||
// runOnBasicBlock - Process a basic block, fixing it up...
|
||||
//
|
||||
bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
|
||||
bool RaiseAllocations::runOnBasicBlock(BasicBlock &BB) {
|
||||
bool Changed = false;
|
||||
BasicBlock::InstListType &BIL = BB->getInstList();
|
||||
BasicBlock::InstListType &BIL = BB.getInstList();
|
||||
|
||||
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
|
||||
Instruction *I = *BI;
|
||||
for (BasicBlock::iterator BI = BB.begin(); BI != BB.end();) {
|
||||
Instruction *I = BI;
|
||||
|
||||
if (CallInst *CI = dyn_cast<CallInst>(I)) {
|
||||
if (CI->getCalledValue() == MallocFunc) { // Replace call to malloc?
|
||||
|
@ -111,7 +111,7 @@ bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
|
|||
// source size.
|
||||
if (Source->getType() != Type::UIntTy) {
|
||||
CastInst *New = new CastInst(Source, Type::UIntTy, "MallocAmtCast");
|
||||
BI = BIL.insert(BI, New)+1;
|
||||
BI = ++BIL.insert(BI, New);
|
||||
Source = New;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
|
|||
if (!isa<PointerType>(Source->getType())) {
|
||||
CastInst *New = new CastInst(Source, PointerType::get(Type::SByteTy),
|
||||
"FreePtrCast");
|
||||
BI = BIL.insert(BI, New)+1;
|
||||
BI = ++BIL.insert(BI, New);
|
||||
Source = New;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace {
|
|||
struct ExternalFuncs {
|
||||
Function *PrintfFunc, *HashPtrFunc, *ReleasePtrFunc;
|
||||
Function *RecordPtrFunc, *PushOnEntryFunc, *ReleaseOnReturnFunc;
|
||||
void doInitialization(Module *M); // Add prototypes for external functions
|
||||
void doInitialization(Module &M); // Add prototypes for external functions
|
||||
};
|
||||
|
||||
class InsertTraceCode : public FunctionPass {
|
||||
|
@ -64,7 +64,7 @@ namespace {
|
|||
|
||||
// Add a prototype for runtime functions not already in the program.
|
||||
//
|
||||
bool doInitialization(Module *M);
|
||||
bool doInitialization(Module &M);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Function InsertCodeToTraceValues
|
||||
|
@ -77,8 +77,8 @@ namespace {
|
|||
|
||||
// runOnFunction - This method does the work.
|
||||
//
|
||||
bool runOnFunction(Function *F) {
|
||||
return doit(F, TraceBasicBlockExits, TraceFunctionExits, externalFuncs);
|
||||
bool runOnFunction(Function &F) {
|
||||
return doit(&F, TraceBasicBlockExits, TraceFunctionExits, externalFuncs);
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
|
@ -98,36 +98,36 @@ Pass *createTraceValuesPassForBasicBlocks() { // Trace BB's and functions
|
|||
|
||||
// Add a prototype for external functions used by the tracing code.
|
||||
//
|
||||
void ExternalFuncs::doInitialization(Module *M) {
|
||||
void ExternalFuncs::doInitialization(Module &M) {
|
||||
const Type *SBP = PointerType::get(Type::SByteTy);
|
||||
const FunctionType *MTy =
|
||||
FunctionType::get(Type::IntTy, vector<const Type*>(1, SBP), true);
|
||||
PrintfFunc = M->getOrInsertFunction("printf", MTy);
|
||||
PrintfFunc = M.getOrInsertFunction("printf", MTy);
|
||||
|
||||
// uint (sbyte*)
|
||||
const FunctionType *hashFuncTy =
|
||||
FunctionType::get(Type::UIntTy, vector<const Type*>(1, SBP), false);
|
||||
HashPtrFunc = M->getOrInsertFunction("HashPointerToSeqNum", hashFuncTy);
|
||||
HashPtrFunc = M.getOrInsertFunction("HashPointerToSeqNum", hashFuncTy);
|
||||
|
||||
// void (sbyte*)
|
||||
const FunctionType *voidSBPFuncTy =
|
||||
FunctionType::get(Type::VoidTy, vector<const Type*>(1, SBP), false);
|
||||
|
||||
ReleasePtrFunc =M->getOrInsertFunction("ReleasePointerSeqNum", voidSBPFuncTy);
|
||||
RecordPtrFunc = M->getOrInsertFunction("RecordPointer", voidSBPFuncTy);
|
||||
ReleasePtrFunc = M.getOrInsertFunction("ReleasePointerSeqNum", voidSBPFuncTy);
|
||||
RecordPtrFunc = M.getOrInsertFunction("RecordPointer", voidSBPFuncTy);
|
||||
|
||||
const FunctionType *voidvoidFuncTy =
|
||||
FunctionType::get(Type::VoidTy, vector<const Type*>(), false);
|
||||
|
||||
PushOnEntryFunc = M->getOrInsertFunction("PushPointerSet", voidvoidFuncTy);
|
||||
ReleaseOnReturnFunc = M->getOrInsertFunction("ReleasePointersPopSet",
|
||||
PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", voidvoidFuncTy);
|
||||
ReleaseOnReturnFunc = M.getOrInsertFunction("ReleasePointersPopSet",
|
||||
voidvoidFuncTy);
|
||||
}
|
||||
|
||||
|
||||
// Add a prototype for external functions used by the tracing code.
|
||||
//
|
||||
bool InsertTraceCode::doInitialization(Module *M) {
|
||||
bool InsertTraceCode::doInitialization(Module &M) {
|
||||
externalFuncs.doInitialization(M);
|
||||
return false;
|
||||
}
|
||||
|
@ -214,20 +214,20 @@ static void InsertPrintInst(Value *V,BasicBlock *BB, BasicBlock::iterator &BBI,
|
|||
new GetElementPtrInst(fmtVal,
|
||||
vector<Value*>(2,ConstantUInt::get(Type::UIntTy, 0)),
|
||||
"trstr");
|
||||
BBI = BB->getInstList().insert(BBI, GEP)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, GEP);
|
||||
|
||||
// Insert a call to the hash function if this is a pointer value
|
||||
if (V && isa<PointerType>(V->getType()) && !DisablePtrHashing) {
|
||||
const Type *SBP = PointerType::get(Type::SByteTy);
|
||||
if (V->getType() != SBP) { // Cast pointer to be sbyte*
|
||||
Instruction *I = new CastInst(V, SBP, "Hash_cast");
|
||||
BBI = BB->getInstList().insert(BBI, I)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
V = I;
|
||||
}
|
||||
|
||||
vector<Value*> HashArgs(1, V);
|
||||
V = new CallInst(HashPtrToSeqNum, HashArgs, "ptrSeqNum");
|
||||
BBI = BB->getInstList().insert(BBI, cast<Instruction>(V))+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, cast<Instruction>(V));
|
||||
}
|
||||
|
||||
// Insert the first print instruction to print the string flag:
|
||||
|
@ -235,7 +235,7 @@ static void InsertPrintInst(Value *V,BasicBlock *BB, BasicBlock::iterator &BBI,
|
|||
PrintArgs.push_back(GEP);
|
||||
if (V) PrintArgs.push_back(V);
|
||||
Instruction *I = new CallInst(Printf, PrintArgs, "trace");
|
||||
BBI = BB->getInstList().insert(BBI, I)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
}
|
||||
|
||||
|
||||
|
@ -257,12 +257,12 @@ InsertReleaseInst(Value *V, BasicBlock *BB,
|
|||
const Type *SBP = PointerType::get(Type::SByteTy);
|
||||
if (V->getType() != SBP) { // Cast pointer to be sbyte*
|
||||
Instruction *I = new CastInst(V, SBP, "RPSN_cast");
|
||||
BBI = BB->getInstList().insert(BBI, I)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
V = I;
|
||||
}
|
||||
vector<Value*> releaseArgs(1, V);
|
||||
Instruction *I = new CallInst(ReleasePtrFunc, releaseArgs);
|
||||
BBI = BB->getInstList().insert(BBI, I)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -272,29 +272,29 @@ InsertRecordInst(Value *V, BasicBlock *BB,
|
|||
const Type *SBP = PointerType::get(Type::SByteTy);
|
||||
if (V->getType() != SBP) { // Cast pointer to be sbyte*
|
||||
Instruction *I = new CastInst(V, SBP, "RP_cast");
|
||||
BBI = BB->getInstList().insert(BBI, I)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
V = I;
|
||||
}
|
||||
vector<Value*> releaseArgs(1, V);
|
||||
Instruction *I = new CallInst(RecordPtrFunc, releaseArgs);
|
||||
BBI = BB->getInstList().insert(BBI, I)+1;
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
}
|
||||
|
||||
static void
|
||||
InsertPushOnEntryFunc(Function *M,
|
||||
Function* PushOnEntryFunc) {
|
||||
// Get an iterator to point to the insertion location
|
||||
BasicBlock *BB = M->getEntryNode();
|
||||
BB->getInstList().insert(BB->begin(), new CallInst(PushOnEntryFunc,
|
||||
vector<Value*> ()));
|
||||
BasicBlock &BB = M->getEntryNode();
|
||||
BB.getInstList().insert(BB.begin(), new CallInst(PushOnEntryFunc,
|
||||
vector<Value*>()));
|
||||
}
|
||||
|
||||
static void
|
||||
InsertReleaseRecordedInst(BasicBlock *BB,
|
||||
Function* ReleaseOnReturnFunc) {
|
||||
BasicBlock::iterator BBI = BB->end()-1;
|
||||
BBI = 1 + BB->getInstList().insert(BBI, new CallInst(ReleaseOnReturnFunc,
|
||||
vector<Value*>()));
|
||||
BasicBlock::iterator BBI = BB->end()--;
|
||||
BBI = ++BB->getInstList().insert(BBI, new CallInst(ReleaseOnReturnFunc,
|
||||
vector<Value*>()));
|
||||
}
|
||||
|
||||
// Look for alloca and free instructions. These are the ptrs to release.
|
||||
|
@ -306,13 +306,13 @@ ReleasePtrSeqNumbers(BasicBlock *BB,
|
|||
ExternalFuncs& externalFuncs) {
|
||||
|
||||
for (BasicBlock::iterator II=BB->begin(); II != BB->end(); ++II) {
|
||||
if (FreeInst *FI = dyn_cast<FreeInst>(*II))
|
||||
if (FreeInst *FI = dyn_cast<FreeInst>(&*II))
|
||||
InsertReleaseInst(FI->getOperand(0), BB,II,externalFuncs.ReleasePtrFunc);
|
||||
else if (AllocaInst *AI = dyn_cast<AllocaInst>(*II))
|
||||
else if (AllocaInst *AI = dyn_cast<AllocaInst>(&*II))
|
||||
{
|
||||
BasicBlock::iterator nextI = II+1;
|
||||
BasicBlock::iterator nextI = ++II;
|
||||
InsertRecordInst(AI, BB, nextI, externalFuncs.RecordPtrFunc);
|
||||
II = nextI - 1;
|
||||
II = --nextI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -335,8 +335,8 @@ static void TraceValuesAtBBExit(BasicBlock *BB,
|
|||
// Get an iterator to point to the insertion location, which is
|
||||
// just before the terminator instruction.
|
||||
//
|
||||
BasicBlock::iterator InsertPos = BB->end()-1;
|
||||
assert((*InsertPos)->isTerminator());
|
||||
BasicBlock::iterator InsertPos = BB->end()--;
|
||||
assert(BB->back().isTerminator());
|
||||
|
||||
// If the terminator is a conditional branch, insert the trace code just
|
||||
// before the instruction that computes the branch condition (just to
|
||||
|
@ -349,14 +349,9 @@ static void TraceValuesAtBBExit(BasicBlock *BB,
|
|||
if (!Branch->isUnconditional())
|
||||
if (Instruction *I = dyn_cast<Instruction>(Branch->getCondition()))
|
||||
if (I->getParent() == BB) {
|
||||
SetCC = I;
|
||||
while (*InsertPos != SetCC)
|
||||
--InsertPos; // Back up until we can insert before the setcc
|
||||
InsertPos = SetCC = I; // Back up until we can insert before the setcc
|
||||
}
|
||||
|
||||
// Copy all of the instructions into a vector to avoid problems with Setcc
|
||||
const vector<Instruction*> Insts(BB->begin(), InsertPos);
|
||||
|
||||
std::ostringstream OutStr;
|
||||
WriteAsOperand(OutStr, BB, false);
|
||||
InsertPrintInst(0, BB, InsertPos, "LEAVING BB:" + OutStr.str(),
|
||||
|
@ -364,39 +359,35 @@ static void TraceValuesAtBBExit(BasicBlock *BB,
|
|||
|
||||
// Insert a print instruction for each value.
|
||||
//
|
||||
for (vector<Instruction*>::const_iterator II = Insts.begin(),
|
||||
IE = Insts.end(); II != IE; ++II) {
|
||||
Instruction *I = *II;
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
||||
for (BasicBlock::iterator II = BB->begin(), IE = InsertPos++; II != IE; ++II){
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(&*II)) {
|
||||
assert(valuesStoredInFunction &&
|
||||
"Should not be printing a store instruction at function exit");
|
||||
LoadInst *LI = new LoadInst(SI->getPointerOperand(), SI->copyIndices(),
|
||||
"reload");
|
||||
InsertPos = BB->getInstList().insert(InsertPos, LI) + 1;
|
||||
"reload."+SI->getPointerOperand()->getName());
|
||||
InsertPos = ++BB->getInstList().insert(InsertPos, LI);
|
||||
valuesStoredInFunction->push_back(LI);
|
||||
}
|
||||
if (ShouldTraceValue(I))
|
||||
InsertVerbosePrintInst(I, BB, InsertPos, " ", Printf, HashPtrToSeqNum);
|
||||
if (ShouldTraceValue(II))
|
||||
InsertVerbosePrintInst(II, BB, InsertPos, " ", Printf, HashPtrToSeqNum);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void InsertCodeToShowFunctionEntry(Function *M, Function *Printf,
|
||||
Function* HashPtrToSeqNum){
|
||||
// Get an iterator to point to the insertion location
|
||||
BasicBlock *BB = M->getEntryNode();
|
||||
BasicBlock::iterator BBI = BB->begin();
|
||||
BasicBlock &BB = M->getEntryNode();
|
||||
BasicBlock::iterator BBI = BB.begin();
|
||||
|
||||
std::ostringstream OutStr;
|
||||
WriteAsOperand(OutStr, M, true);
|
||||
InsertPrintInst(0, BB, BBI, "ENTERING FUNCTION: " + OutStr.str(),
|
||||
InsertPrintInst(0, &BB, BBI, "ENTERING FUNCTION: " + OutStr.str(),
|
||||
Printf, HashPtrToSeqNum);
|
||||
|
||||
// Now print all the incoming arguments
|
||||
const Function::ArgumentListType &argList = M->getArgumentList();
|
||||
unsigned ArgNo = 0;
|
||||
for (Function::ArgumentListType::const_iterator
|
||||
I = argList.begin(), E = argList.end(); I != E; ++I, ++ArgNo) {
|
||||
InsertVerbosePrintInst((Value*)*I, BB, BBI,
|
||||
for (Function::aiterator I = M->abegin(), E = M->aend(); I != E; ++I,++ArgNo){
|
||||
InsertVerbosePrintInst(I, &BB, BBI,
|
||||
" Arg #" + utostr(ArgNo) + ": ", Printf,
|
||||
HashPtrToSeqNum);
|
||||
}
|
||||
|
@ -407,8 +398,8 @@ static inline void InsertCodeToShowFunctionExit(BasicBlock *BB,
|
|||
Function *Printf,
|
||||
Function* HashPtrToSeqNum) {
|
||||
// Get an iterator to point to the insertion location
|
||||
BasicBlock::iterator BBI = BB->end()-1;
|
||||
ReturnInst *Ret = cast<ReturnInst>(*BBI);
|
||||
BasicBlock::iterator BBI = BB->end()--;
|
||||
ReturnInst &Ret = cast<ReturnInst>(BB->back());
|
||||
|
||||
std::ostringstream OutStr;
|
||||
WriteAsOperand(OutStr, BB->getParent(), true);
|
||||
|
@ -417,7 +408,7 @@ static inline void InsertCodeToShowFunctionExit(BasicBlock *BB,
|
|||
|
||||
// print the return value, if any
|
||||
if (BB->getParent()->getReturnType() != Type::VoidTy)
|
||||
InsertPrintInst(Ret->getReturnValue(), BB, BBI, " Returning: ",
|
||||
InsertPrintInst(Ret.getReturnValue(), BB, BBI, " Returning: ",
|
||||
Printf, HashPtrToSeqNum);
|
||||
}
|
||||
|
||||
|
@ -443,8 +434,7 @@ bool InsertTraceCode::doit(Function *M, bool traceBasicBlockExits,
|
|||
if (!DisablePtrHashing)
|
||||
InsertPushOnEntryFunc(M, externalFuncs.PushOnEntryFunc);
|
||||
|
||||
for (Function::iterator BI = M->begin(); BI != M->end(); ++BI) {
|
||||
BasicBlock *BB = *BI;
|
||||
for (Function::iterator BB = M->begin(); BB != M->end(); ++BB) {
|
||||
if (isa<ReturnInst>(BB->getTerminator()))
|
||||
exitBlocks.push_back(BB); // record this as an exit block
|
||||
|
||||
|
|
|
@ -58,13 +58,13 @@ static inline bool isReinterpretingCast(const CastInst *CI) {
|
|||
//
|
||||
static bool HandleCastToPointer(BasicBlock::iterator BI,
|
||||
const PointerType *DestPTy) {
|
||||
CastInst *CI = cast<CastInst>(*BI);
|
||||
if (CI->use_empty()) return false;
|
||||
CastInst &CI = cast<CastInst>(*BI);
|
||||
if (CI.use_empty()) return false;
|
||||
|
||||
// Scan all of the uses, looking for any uses that are not add
|
||||
// instructions. If we have non-adds, do not make this transformation.
|
||||
//
|
||||
for (Value::use_iterator I = CI->use_begin(), E = CI->use_end();
|
||||
for (Value::use_iterator I = CI.use_begin(), E = CI.use_end();
|
||||
I != E; ++I) {
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*I)) {
|
||||
if (BO->getOpcode() != Instruction::Add)
|
||||
|
@ -75,7 +75,7 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
|
|||
}
|
||||
|
||||
std::vector<Value*> Indices;
|
||||
Value *Src = CI->getOperand(0);
|
||||
Value *Src = CI.getOperand(0);
|
||||
const Type *Result = ConvertableToGEP(DestPTy, Src, Indices, &BI);
|
||||
if (Result == 0) return false; // Not convertable...
|
||||
|
||||
|
@ -83,13 +83,13 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
|
|||
|
||||
// If we have a getelementptr capability... transform all of the
|
||||
// add instruction uses into getelementptr's.
|
||||
while (!CI->use_empty()) {
|
||||
BinaryOperator *I = cast<BinaryOperator>(*CI->use_begin());
|
||||
while (!CI.use_empty()) {
|
||||
BinaryOperator *I = cast<BinaryOperator>(*CI.use_begin());
|
||||
assert(I->getOpcode() == Instruction::Add && I->getNumOperands() == 2 &&
|
||||
"Use is not a valid add instruction!");
|
||||
|
||||
// Get the value added to the cast result pointer...
|
||||
Value *OtherPtr = I->getOperand((I->getOperand(0) == CI) ? 1 : 0);
|
||||
Value *OtherPtr = I->getOperand((I->getOperand(0) == &CI) ? 1 : 0);
|
||||
|
||||
Instruction *GEP = new GetElementPtrInst(OtherPtr, Indices, I->getName());
|
||||
PRINT_PEEPHOLE1("cast-add-to-gep:i", I);
|
||||
|
@ -102,16 +102,14 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
|
|||
// add instruction type, insert a cast now.
|
||||
//
|
||||
|
||||
// Insert the GEP instruction before the old add instruction... and get an
|
||||
// iterator to point at the add instruction...
|
||||
BasicBlock::iterator GEPI = InsertInstBeforeInst(GEP, I)+1;
|
||||
// Insert the GEP instruction before the old add instruction...
|
||||
I->getParent()->getInstList().insert(I, GEP);
|
||||
|
||||
PRINT_PEEPHOLE1("cast-add-to-gep:o", GEP);
|
||||
CastInst *CI = new CastInst(GEP, I->getType());
|
||||
GEP = CI;
|
||||
GEP = new CastInst(GEP, I->getType());
|
||||
|
||||
// Replace the old add instruction with the shiny new GEP inst
|
||||
ReplaceInstWithInst(I->getParent()->getInstList(), GEPI, GEP);
|
||||
ReplaceInstWithInst(I, GEP);
|
||||
}
|
||||
|
||||
PRINT_PEEPHOLE1("cast-add-to-gep:o", GEP);
|
||||
|
@ -160,7 +158,7 @@ static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI,
|
|||
|
||||
GetElementPtrInst *GEP = new GetElementPtrInst(SrcPtr, Indices,
|
||||
AddOp2->getName());
|
||||
BI = BB->getInstList().insert(BI, GEP)+1;
|
||||
BI = ++BB->getInstList().insert(BI, GEP);
|
||||
|
||||
Instruction *NCI = new CastInst(GEP, AddOp1->getType());
|
||||
ReplaceInstWithInst(BB->getInstList(), BI, NCI);
|
||||
|
@ -169,7 +167,7 @@ static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI,
|
|||
}
|
||||
|
||||
static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||
Instruction *I = *BI;
|
||||
Instruction *I = BI;
|
||||
|
||||
if (CastInst *CI = dyn_cast<CastInst>(I)) {
|
||||
Value *Src = CI->getOperand(0);
|
||||
|
@ -193,7 +191,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
// DCE the instruction now, to avoid having the iterative version of DCE
|
||||
// have to worry about it.
|
||||
//
|
||||
delete BB->getInstList().remove(BI);
|
||||
BI = BB->getInstList().erase(BI);
|
||||
|
||||
++NumCastOfCast;
|
||||
return true;
|
||||
|
@ -326,7 +324,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
GetElementPtrInst *GEP = new GetElementPtrInst(Src, Indices,
|
||||
CI->getName());
|
||||
CI->setName("");
|
||||
BI = BB->getInstList().insert(BI, GEP)+1;
|
||||
BI = ++BB->getInstList().insert(BI, GEP);
|
||||
|
||||
// Make the old cast instruction reference the new GEP instead of
|
||||
// the old src value.
|
||||
|
@ -359,7 +357,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
//
|
||||
if (CastInst *CI = dyn_cast<CastInst>(Pointer))
|
||||
if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
|
||||
if (PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
|
||||
if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
|
||||
// convertable types?
|
||||
if (Val->getType()->isLosslesslyConvertableTo(CSPT->getElementType()) &&
|
||||
!SI->hasIndices()) { // No subscripts yet!
|
||||
|
@ -369,7 +367,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
CastInst *NCI = new CastInst(Val, CSPT->getElementType(),
|
||||
CI->getName());
|
||||
CI->setName("");
|
||||
BI = BB->getInstList().insert(BI, NCI)+1;
|
||||
BI = ++BB->getInstList().insert(BI, NCI);
|
||||
|
||||
// Replace the old store with a new one!
|
||||
ReplaceInstWithInst(BB->getInstList(), BI,
|
||||
|
@ -399,7 +397,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
//
|
||||
if (CastInst *CI = dyn_cast<CastInst>(Pointer))
|
||||
if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
|
||||
if (PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
|
||||
if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
|
||||
// convertable types?
|
||||
if (PtrElType->isLosslesslyConvertableTo(CSPT->getElementType()) &&
|
||||
!LI->hasIndices()) { // No subscripts yet!
|
||||
|
@ -410,7 +408,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
|
||||
// Insert the new T cast instruction... stealing old T's name
|
||||
CastInst *NCI = new CastInst(NewLI, LI->getType(), CI->getName());
|
||||
BI = BB->getInstList().insert(BI, NewLI)+1;
|
||||
BI = ++BB->getInstList().insert(BI, NewLI);
|
||||
|
||||
// Replace the old store with a new one!
|
||||
ReplaceInstWithInst(BB->getInstList(), BI, NCI);
|
||||
|
@ -435,24 +433,22 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
|
||||
|
||||
|
||||
static bool DoRaisePass(Function *F) {
|
||||
static bool DoRaisePass(Function &F) {
|
||||
bool Changed = false;
|
||||
for (Function::iterator MI = F->begin(), ME = F->end(); MI != ME; ++MI) {
|
||||
BasicBlock *BB = *MI;
|
||||
BasicBlock::InstListType &BIL = BB->getInstList();
|
||||
|
||||
for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB)
|
||||
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
|
||||
DEBUG(cerr << "Processing: " << *BI);
|
||||
if (dceInstruction(BI) || doConstantPropogation(BI)) {
|
||||
Changed = true;
|
||||
++NumDCEorCP;
|
||||
DEBUG(cerr << "***\t\t^^-- DeadCode Elinated!\n");
|
||||
} else if (PeepholeOptimize(BB, BI))
|
||||
} else if (PeepholeOptimize(BB, BI)) {
|
||||
Changed = true;
|
||||
else
|
||||
} else {
|
||||
++BI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
|
@ -460,8 +456,8 @@ static bool DoRaisePass(Function *F) {
|
|||
// RaisePointerReferences::doit - Raise a function representation to a higher
|
||||
// level.
|
||||
//
|
||||
static bool doRPR(Function *F) {
|
||||
DEBUG(cerr << "\n\n\nStarting to work on Function '" << F->getName()<< "'\n");
|
||||
static bool doRPR(Function &F) {
|
||||
DEBUG(cerr << "\n\n\nStarting to work on Function '" << F.getName() << "'\n");
|
||||
|
||||
// Insert casts for all incoming pointer pointer values that are treated as
|
||||
// arrays...
|
||||
|
@ -486,7 +482,7 @@ namespace {
|
|||
struct RaisePointerReferences : public FunctionPass {
|
||||
const char *getPassName() const { return "Raise Pointer References"; }
|
||||
|
||||
virtual bool runOnFunction(Function *F) { return doRPR(F); }
|
||||
virtual bool runOnFunction(Function &F) { return doRPR(F); }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.preservesCFG();
|
||||
|
|
|
@ -46,8 +46,8 @@ public:
|
|||
|
||||
// Execute the Aggressive Dead Code Elimination Algorithm
|
||||
//
|
||||
virtual bool runOnFunction(Function *F) {
|
||||
Func = F;
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
Func = &F;
|
||||
bool Changed = doADCE();
|
||||
assert(WorkList.empty());
|
||||
LiveSet.clear();
|
||||
|
@ -126,14 +126,12 @@ bool ADCE::doADCE() {
|
|||
BBI != BBE; ++BBI) {
|
||||
BasicBlock *BB = *BBI;
|
||||
for (BasicBlock::iterator II = BB->begin(), EI = BB->end(); II != EI; ) {
|
||||
Instruction *I = *II;
|
||||
|
||||
if (I->hasSideEffects() || I->getOpcode() == Instruction::Ret) {
|
||||
markInstructionLive(I);
|
||||
if (II->hasSideEffects() || II->getOpcode() == Instruction::Ret) {
|
||||
markInstructionLive(II);
|
||||
++II; // Increment the inst iterator if the inst wasn't deleted
|
||||
} else if (isInstructionTriviallyDead(I)) {
|
||||
} else if (isInstructionTriviallyDead(II)) {
|
||||
// Remove the instruction from it's basic block...
|
||||
delete BB->getInstList().remove(II);
|
||||
II = BB->getInstList().erase(II);
|
||||
++NumInstRemoved;
|
||||
MadeChanges = true;
|
||||
} else {
|
||||
|
@ -185,9 +183,8 @@ bool ADCE::doADCE() {
|
|||
if (DebugFlag) {
|
||||
cerr << "Current Function: X = Live\n";
|
||||
for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
|
||||
for (BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end();
|
||||
BI != BE; ++BI) {
|
||||
if (LiveSet.count(*BI)) cerr << "X ";
|
||||
for (BasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE; ++BI){
|
||||
if (LiveSet.count(BI)) cerr << "X ";
|
||||
cerr << *BI;
|
||||
}
|
||||
}
|
||||
|
@ -201,8 +198,8 @@ bool ADCE::doADCE() {
|
|||
if (AliveBlocks.size() != Func->size()) {
|
||||
// Insert a new entry node to eliminate the entry node as a special case.
|
||||
BasicBlock *NewEntry = new BasicBlock();
|
||||
NewEntry->getInstList().push_back(new BranchInst(Func->front()));
|
||||
Func->getBasicBlocks().push_front(NewEntry);
|
||||
NewEntry->getInstList().push_back(new BranchInst(&Func->front()));
|
||||
Func->getBasicBlockList().push_front(NewEntry);
|
||||
AliveBlocks.insert(NewEntry); // This block is always alive!
|
||||
|
||||
// Loop over all of the alive blocks in the function. If any successor
|
||||
|
@ -211,8 +208,8 @@ bool ADCE::doADCE() {
|
|||
// the block to reflect this.
|
||||
//
|
||||
for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
|
||||
if (AliveBlocks.count(*I)) {
|
||||
BasicBlock *BB = *I;
|
||||
if (AliveBlocks.count(I)) {
|
||||
BasicBlock *BB = I;
|
||||
TerminatorInst *TI = BB->getTerminator();
|
||||
|
||||
// Loop over all of the successors, looking for ones that are not alive
|
||||
|
@ -242,7 +239,7 @@ bool ADCE::doADCE() {
|
|||
// should be identical to the incoming values for LastDead.
|
||||
//
|
||||
for (BasicBlock::iterator II = NextAlive->begin();
|
||||
PHINode *PN = dyn_cast<PHINode>(*II); ++II) {
|
||||
PHINode *PN = dyn_cast<PHINode>(&*II); ++II) {
|
||||
// Get the incoming value for LastDead...
|
||||
int OldIdx = PN->getBasicBlockIndex(LastDead);
|
||||
assert(OldIdx != -1 && "LastDead is not a pred of NextAlive!");
|
||||
|
@ -258,17 +255,16 @@ bool ADCE::doADCE() {
|
|||
// sweep over the program can safely delete dead instructions without
|
||||
// other dead instructions still refering to them.
|
||||
//
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end()-1; I != E; ++I)
|
||||
if (!LiveSet.count(*I)) // Is this instruction alive?
|
||||
(*I)->dropAllReferences(); // Nope, drop references...
|
||||
for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; ++I)
|
||||
if (!LiveSet.count(I)) // Is this instruction alive?
|
||||
I->dropAllReferences(); // Nope, drop references...
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over all of the basic blocks in the function, dropping references of
|
||||
// the dead basic blocks
|
||||
//
|
||||
for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I) {
|
||||
BasicBlock *BB = *I;
|
||||
for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) {
|
||||
if (!AliveBlocks.count(BB)) {
|
||||
// Remove all outgoing edges from this basic block and convert the
|
||||
// terminator into a return instruction.
|
||||
|
@ -283,7 +279,7 @@ bool ADCE::doADCE() {
|
|||
}
|
||||
|
||||
// Delete the old terminator instruction...
|
||||
delete BB->getInstList().remove(BB->end()-1);
|
||||
BB->getInstList().pop_back();
|
||||
const Type *RetTy = Func->getReturnType();
|
||||
Instruction *New = new ReturnInst(RetTy != Type::VoidTy ?
|
||||
Constant::getNullValue(RetTy) : 0);
|
||||
|
@ -302,14 +298,13 @@ bool ADCE::doADCE() {
|
|||
// instructions from alive blocks.
|
||||
//
|
||||
for (Function::iterator BI = Func->begin(); BI != Func->end(); )
|
||||
if (!AliveBlocks.count(*BI))
|
||||
delete Func->getBasicBlocks().remove(BI);
|
||||
if (!AliveBlocks.count(BI))
|
||||
BI = Func->getBasicBlockList().erase(BI);
|
||||
else {
|
||||
BasicBlock *BB = *BI;
|
||||
for (BasicBlock::iterator II = BB->begin(); II != BB->end()-1; )
|
||||
if (!LiveSet.count(*II)) { // Is this instruction alive?
|
||||
for (BasicBlock::iterator II = BI->begin(); II != --BI->end(); )
|
||||
if (!LiveSet.count(II)) { // Is this instruction alive?
|
||||
// Nope... remove the instruction from it's basic block...
|
||||
delete BB->getInstList().remove(II);
|
||||
II = BI->getInstList().erase(II);
|
||||
++NumInstRemoved;
|
||||
MadeChanges = true;
|
||||
} else {
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace {
|
|||
struct ConstantPropogation : public FunctionPass {
|
||||
const char *getPassName() const { return "Simple Constant Propogation"; }
|
||||
|
||||
bool runOnFunction(Function *F);
|
||||
bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.preservesCFG();
|
||||
|
@ -39,7 +39,7 @@ Pass *createConstantPropogationPass() {
|
|||
}
|
||||
|
||||
|
||||
bool ConstantPropogation::runOnFunction(Function *F) {
|
||||
bool ConstantPropogation::runOnFunction(Function &F) {
|
||||
// Initialize the worklist to all of the instructions ready to process...
|
||||
std::set<Instruction*> WorkList(inst_begin(F), inst_end(F));
|
||||
bool Changed = false;
|
||||
|
|
|
@ -28,10 +28,9 @@ namespace {
|
|||
struct DeadInstElimination : public BasicBlockPass {
|
||||
const char *getPassName() const { return "Dead Instruction Elimination"; }
|
||||
|
||||
virtual bool runOnBasicBlock(BasicBlock *BB) {
|
||||
BasicBlock::InstListType &Vals = BB->getInstList();
|
||||
virtual bool runOnBasicBlock(BasicBlock &BB) {
|
||||
bool Changed = false;
|
||||
for (BasicBlock::iterator DI = Vals.begin(); DI != Vals.end(); )
|
||||
for (BasicBlock::iterator DI = BB.begin(); DI != BB.end(); )
|
||||
if (dceInstruction(DI)) {
|
||||
Changed = true;
|
||||
++DIEEliminated;
|
||||
|
@ -60,7 +59,7 @@ namespace {
|
|||
struct DCE : public FunctionPass {
|
||||
const char *getPassName() const { return "Dead Code Elimination"; }
|
||||
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.preservesCFG();
|
||||
|
@ -68,7 +67,7 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
bool DCE::runOnFunction(Function *F) {
|
||||
bool DCE::runOnFunction(Function &F) {
|
||||
// Start out with all of the instructions in the worklist...
|
||||
std::vector<Instruction*> WorkList(inst_begin(F), inst_end(F));
|
||||
std::set<Instruction*> DeadInsts;
|
||||
|
@ -103,16 +102,14 @@ bool DCE::runOnFunction(Function *F) {
|
|||
if (DeadInsts.empty()) return false;
|
||||
|
||||
// Otherwise, loop over the program, removing and deleting the instructions...
|
||||
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
|
||||
BasicBlock::InstListType &BBIL = (*I)->getInstList();
|
||||
for (BasicBlock::iterator BI = BBIL.begin(); BI != BBIL.end(); )
|
||||
if (DeadInsts.count(*BI)) { // Is this instruction dead?
|
||||
delete BBIL.remove(BI); // Yup, remove and delete inst
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
|
||||
for (BasicBlock::iterator BI = I->begin(); BI != I->end(); )
|
||||
if (DeadInsts.count(BI)) { // Is this instruction dead?
|
||||
BI = I->getInstList().erase(BI); // Yup, remove and delete inst
|
||||
++DCEEliminated;
|
||||
} else { // This instruction is not dead
|
||||
++BI; // Continue on to the next one...
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace {
|
|||
struct DecomposePass : public BasicBlockPass {
|
||||
const char *getPassName() const { return "Decompose Subscripting Exps"; }
|
||||
|
||||
virtual bool runOnBasicBlock(BasicBlock *BB);
|
||||
virtual bool runOnBasicBlock(BasicBlock &BB);
|
||||
|
||||
private:
|
||||
static void decomposeArrayRef(BasicBlock::iterator &BBI);
|
||||
|
@ -38,10 +38,10 @@ Pass *createDecomposeMultiDimRefsPass() {
|
|||
// runOnBasicBlock - Entry point for array or structure references with multiple
|
||||
// indices.
|
||||
//
|
||||
bool DecomposePass::runOnBasicBlock(BasicBlock *BB) {
|
||||
bool DecomposePass::runOnBasicBlock(BasicBlock &BB) {
|
||||
bool Changed = false;
|
||||
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ) {
|
||||
if (MemAccessInst *MAI = dyn_cast<MemAccessInst>(*II)) {
|
||||
for (BasicBlock::iterator II = BB.begin(); II != BB.end(); ) {
|
||||
if (MemAccessInst *MAI = dyn_cast<MemAccessInst>(&*II)) {
|
||||
if (MAI->getNumOperands() > MAI->getFirstIndexOperandNumber()+1) {
|
||||
decomposeArrayRef(II);
|
||||
Changed = true;
|
||||
|
@ -67,9 +67,9 @@ bool DecomposePass::runOnBasicBlock(BasicBlock *BB) {
|
|||
// If any index is (uint) 0, we omit the getElementPtr instruction.
|
||||
//
|
||||
void DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) {
|
||||
MemAccessInst *MAI = cast<MemAccessInst>(*BBI);
|
||||
BasicBlock *BB = MAI->getParent();
|
||||
Value *LastPtr = MAI->getPointerOperand();
|
||||
MemAccessInst &MAI = cast<MemAccessInst>(*BBI);
|
||||
BasicBlock *BB = MAI.getParent();
|
||||
Value *LastPtr = MAI.getPointerOperand();
|
||||
|
||||
// Remove the instruction from the stream
|
||||
BB->getInstList().remove(BBI);
|
||||
|
@ -78,22 +78,22 @@ void DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) {
|
|||
|
||||
// Process each index except the last one.
|
||||
//
|
||||
User::const_op_iterator OI = MAI->idx_begin(), OE = MAI->idx_end();
|
||||
User::const_op_iterator OI = MAI.idx_begin(), OE = MAI.idx_end();
|
||||
for (; OI+1 != OE; ++OI) {
|
||||
assert(isa<PointerType>(LastPtr->getType()));
|
||||
|
||||
// Check for a zero index. This will need a cast instead of
|
||||
// a getElementPtr, or it may need neither.
|
||||
bool indexIsZero = isa<Constant>(*OI) &&
|
||||
cast<Constant>(*OI)->isNullValue() &&
|
||||
(*OI)->getType() == Type::UIntTy;
|
||||
cast<Constant>(OI->get())->isNullValue() &&
|
||||
OI->get()->getType() == Type::UIntTy;
|
||||
|
||||
// Extract the first index. If the ptr is a pointer to a structure
|
||||
// and the next index is a structure offset (i.e., not an array offset),
|
||||
// we need to include an initial [0] to index into the pointer.
|
||||
//
|
||||
vector<Value*> Indices;
|
||||
PointerType *PtrTy = cast<PointerType>(LastPtr->getType());
|
||||
const PointerType *PtrTy = cast<PointerType>(LastPtr->getType());
|
||||
if (isa<StructType>(PtrTy->getElementType())
|
||||
&& !PtrTy->indexValid(*OI))
|
||||
Indices.push_back(Constant::getNullValue(Type::UIntTy));
|
||||
|
@ -131,7 +131,7 @@ void DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) {
|
|||
//
|
||||
// Now create a new instruction to replace the original one
|
||||
//
|
||||
PointerType *PtrTy = cast<PointerType>(LastPtr->getType());
|
||||
const PointerType *PtrTy = cast<PointerType>(LastPtr->getType());
|
||||
|
||||
// First, get the final index vector. As above, we may need an initial [0].
|
||||
vector<Value*> Indices;
|
||||
|
@ -142,15 +142,15 @@ void DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) {
|
|||
Indices.push_back(*OI);
|
||||
|
||||
Instruction *NewI = 0;
|
||||
switch(MAI->getOpcode()) {
|
||||
switch(MAI.getOpcode()) {
|
||||
case Instruction::Load:
|
||||
NewI = new LoadInst(LastPtr, Indices, MAI->getName());
|
||||
NewI = new LoadInst(LastPtr, Indices, MAI.getName());
|
||||
break;
|
||||
case Instruction::Store:
|
||||
NewI = new StoreInst(MAI->getOperand(0), LastPtr, Indices);
|
||||
NewI = new StoreInst(MAI.getOperand(0), LastPtr, Indices);
|
||||
break;
|
||||
case Instruction::GetElementPtr:
|
||||
NewI = new GetElementPtrInst(LastPtr, Indices, MAI->getName());
|
||||
NewI = new GetElementPtrInst(LastPtr, Indices, MAI.getName());
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unrecognized memory access instruction");
|
||||
|
@ -158,14 +158,15 @@ void DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) {
|
|||
NewInsts.push_back(NewI);
|
||||
|
||||
// Replace all uses of the old instruction with the new
|
||||
MAI->replaceAllUsesWith(NewI);
|
||||
MAI.replaceAllUsesWith(NewI);
|
||||
|
||||
// Now delete the old instruction...
|
||||
delete MAI;
|
||||
delete &MAI;
|
||||
|
||||
// Insert all of the new instructions...
|
||||
BBI = BB->getInstList().insert(BBI, NewInsts.begin(), NewInsts.end());
|
||||
BB->getInstList().insert(BBI, NewInsts.begin(), NewInsts.end());
|
||||
|
||||
// Advance the iterator to the instruction following the one just inserted...
|
||||
BBI += NewInsts.size();
|
||||
BBI = NewInsts.back();
|
||||
++BBI;
|
||||
}
|
||||
|
|
|
@ -43,21 +43,21 @@ namespace {
|
|||
return "Global Common Subexpression Elimination";
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
// Visitation methods, these are invoked depending on the type of
|
||||
// instruction being checked. They should return true if a common
|
||||
// subexpression was folded.
|
||||
//
|
||||
bool visitUnaryOperator(Instruction *I);
|
||||
bool visitBinaryOperator(Instruction *I);
|
||||
bool visitGetElementPtrInst(GetElementPtrInst *I);
|
||||
bool visitCastInst(CastInst *I){return visitUnaryOperator((Instruction*)I);}
|
||||
bool visitShiftInst(ShiftInst *I) {
|
||||
return visitBinaryOperator((Instruction*)I);
|
||||
bool visitUnaryOperator(Instruction &I);
|
||||
bool visitBinaryOperator(Instruction &I);
|
||||
bool visitGetElementPtrInst(GetElementPtrInst &I);
|
||||
bool visitCastInst(CastInst &I){return visitUnaryOperator((Instruction&)I);}
|
||||
bool visitShiftInst(ShiftInst &I) {
|
||||
return visitBinaryOperator((Instruction&)I);
|
||||
}
|
||||
bool visitLoadInst(LoadInst *LI);
|
||||
bool visitInstruction(Instruction *) { return false; }
|
||||
bool visitLoadInst(LoadInst &LI);
|
||||
bool visitInstruction(Instruction &) { return false; }
|
||||
|
||||
private:
|
||||
void ReplaceInstWithInst(Instruction *First, BasicBlock::iterator SI);
|
||||
|
@ -93,7 +93,7 @@ Pass *createGCSEPass() { return new GCSE(); }
|
|||
// GCSE::runOnFunction - This is the main transformation entry point for a
|
||||
// function.
|
||||
//
|
||||
bool GCSE::runOnFunction(Function *F) {
|
||||
bool GCSE::runOnFunction(Function &F) {
|
||||
bool Changed = false;
|
||||
|
||||
DomSetInfo = &getAnalysis<DominatorSet>();
|
||||
|
@ -110,7 +110,7 @@ bool GCSE::runOnFunction(Function *F) {
|
|||
// program. If so, eliminate them!
|
||||
//
|
||||
while (!WorkList.empty()) {
|
||||
Instruction *I = *WorkList.begin(); // Get an instruction from the worklist
|
||||
Instruction &I = **WorkList.begin(); // Get an instruction from the worklist
|
||||
WorkList.erase(WorkList.begin());
|
||||
|
||||
// Visit the instruction, dispatching to the correct visit function based on
|
||||
|
@ -131,7 +131,7 @@ bool GCSE::runOnFunction(Function *F) {
|
|||
// uses of the instruction use First now instead.
|
||||
//
|
||||
void GCSE::ReplaceInstWithInst(Instruction *First, BasicBlock::iterator SI) {
|
||||
Instruction *Second = *SI;
|
||||
Instruction &Second = *SI;
|
||||
|
||||
//cerr << "DEL " << (void*)Second << Second;
|
||||
|
||||
|
@ -139,15 +139,15 @@ void GCSE::ReplaceInstWithInst(Instruction *First, BasicBlock::iterator SI) {
|
|||
WorkList.insert(First);
|
||||
|
||||
// Add all uses of the second instruction to the worklist
|
||||
for (Value::use_iterator UI = Second->use_begin(), UE = Second->use_end();
|
||||
for (Value::use_iterator UI = Second.use_begin(), UE = Second.use_end();
|
||||
UI != UE; ++UI)
|
||||
WorkList.insert(cast<Instruction>(*UI));
|
||||
|
||||
// Make all users of 'Second' now use 'First'
|
||||
Second->replaceAllUsesWith(First);
|
||||
Second.replaceAllUsesWith(First);
|
||||
|
||||
// Erase the second instruction from the program
|
||||
delete Second->getParent()->getInstList().remove(SI);
|
||||
Second.getParent()->getInstList().erase(SI);
|
||||
}
|
||||
|
||||
// CommonSubExpressionFound - The two instruction I & Other have been found to
|
||||
|
@ -170,16 +170,15 @@ void GCSE::CommonSubExpressionFound(Instruction *I, Instruction *Other) {
|
|||
//
|
||||
// Scan the basic block looking for the "first" instruction
|
||||
BasicBlock::iterator BI = BB1->begin();
|
||||
while (*BI != I && *BI != Other) {
|
||||
while (&*BI != I && &*BI != Other) {
|
||||
++BI;
|
||||
assert(BI != BB1->end() && "Instructions not found in parent BB!");
|
||||
}
|
||||
|
||||
// Keep track of which instructions occurred first & second
|
||||
Instruction *First = *BI;
|
||||
Instruction *First = BI;
|
||||
Instruction *Second = I != First ? I : Other; // Get iterator to second inst
|
||||
BI = find(BI, BB1->end(), Second);
|
||||
assert(BI != BB1->end() && "Second instruction not found in parent block!");
|
||||
BI = Second;
|
||||
|
||||
// Destroy Second, using First instead.
|
||||
ReplaceInstWithInst(First, BI);
|
||||
|
@ -188,13 +187,9 @@ void GCSE::CommonSubExpressionFound(Instruction *I, Instruction *Other) {
|
|||
// dominates the other instruction, we can simply use it
|
||||
//
|
||||
} else if (DomSetInfo->dominates(BB1, BB2)) { // I dom Other?
|
||||
BasicBlock::iterator BI = find(BB2->begin(), BB2->end(), Other);
|
||||
assert(BI != BB2->end() && "Other not in parent basic block!");
|
||||
ReplaceInstWithInst(I, BI);
|
||||
ReplaceInstWithInst(I, Other);
|
||||
} else if (DomSetInfo->dominates(BB2, BB1)) { // Other dom I?
|
||||
BasicBlock::iterator BI = find(BB1->begin(), BB1->end(), I);
|
||||
assert(BI != BB1->end() && "I not in parent basic block!");
|
||||
ReplaceInstWithInst(Other, BI);
|
||||
ReplaceInstWithInst(Other, I);
|
||||
} else {
|
||||
// Handle the most general case now. In this case, neither I dom Other nor
|
||||
// Other dom I. Because we are in SSA form, we are guaranteed that the
|
||||
|
@ -215,12 +210,10 @@ void GCSE::CommonSubExpressionFound(Instruction *I, Instruction *Other) {
|
|||
|
||||
// Rip 'I' out of BB1, and move it to the end of SharedDom.
|
||||
BB1->getInstList().remove(I);
|
||||
SharedDom->getInstList().insert(SharedDom->end()-1, I);
|
||||
SharedDom->getInstList().insert(--SharedDom->end(), I);
|
||||
|
||||
// Eliminate 'Other' now.
|
||||
BasicBlock::iterator BI = find(BB2->begin(), BB2->end(), Other);
|
||||
assert(BI != BB2->end() && "I not in parent basic block!");
|
||||
ReplaceInstWithInst(I, BI);
|
||||
ReplaceInstWithInst(I, Other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,25 +224,25 @@ void GCSE::CommonSubExpressionFound(Instruction *I, Instruction *Other) {
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool GCSE::visitUnaryOperator(Instruction *I) {
|
||||
Value *Op = I->getOperand(0);
|
||||
Function *F = I->getParent()->getParent();
|
||||
bool GCSE::visitUnaryOperator(Instruction &I) {
|
||||
Value *Op = I.getOperand(0);
|
||||
Function *F = I.getParent()->getParent();
|
||||
|
||||
for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end();
|
||||
UI != UE; ++UI)
|
||||
if (Instruction *Other = dyn_cast<Instruction>(*UI))
|
||||
// Check to see if this new binary operator is not I, but same operand...
|
||||
if (Other != I && Other->getOpcode() == I->getOpcode() &&
|
||||
if (Other != &I && Other->getOpcode() == I.getOpcode() &&
|
||||
Other->getOperand(0) == Op && // Is the operand the same?
|
||||
// Is it embeded in the same function? (This could be false if LHS
|
||||
// is a constant or global!)
|
||||
Other->getParent()->getParent() == F &&
|
||||
|
||||
// Check that the types are the same, since this code handles casts...
|
||||
Other->getType() == I->getType()) {
|
||||
Other->getType() == I.getType()) {
|
||||
|
||||
// These instructions are identical. Handle the situation.
|
||||
CommonSubExpressionFound(I, Other);
|
||||
CommonSubExpressionFound(&I, Other);
|
||||
return true; // One instruction eliminated!
|
||||
}
|
||||
|
||||
|
@ -259,45 +252,45 @@ bool GCSE::visitUnaryOperator(Instruction *I) {
|
|||
// isIdenticalBinaryInst - Return true if the two binary instructions are
|
||||
// identical.
|
||||
//
|
||||
static inline bool isIdenticalBinaryInst(const Instruction *I1,
|
||||
static inline bool isIdenticalBinaryInst(const Instruction &I1,
|
||||
const Instruction *I2) {
|
||||
// Is it embeded in the same function? (This could be false if LHS
|
||||
// is a constant or global!)
|
||||
if (I1->getOpcode() != I2->getOpcode() ||
|
||||
I1->getParent()->getParent() != I2->getParent()->getParent())
|
||||
if (I1.getOpcode() != I2->getOpcode() ||
|
||||
I1.getParent()->getParent() != I2->getParent()->getParent())
|
||||
return false;
|
||||
|
||||
// They are identical if both operands are the same!
|
||||
if (I1->getOperand(0) == I2->getOperand(0) &&
|
||||
I1->getOperand(1) == I2->getOperand(1))
|
||||
if (I1.getOperand(0) == I2->getOperand(0) &&
|
||||
I1.getOperand(1) == I2->getOperand(1))
|
||||
return true;
|
||||
|
||||
// If the instruction is commutative and associative, the instruction can
|
||||
// match if the operands are swapped!
|
||||
//
|
||||
if ((I1->getOperand(0) == I2->getOperand(1) &&
|
||||
I1->getOperand(1) == I2->getOperand(0)) &&
|
||||
(I1->getOpcode() == Instruction::Add ||
|
||||
I1->getOpcode() == Instruction::Mul ||
|
||||
I1->getOpcode() == Instruction::And ||
|
||||
I1->getOpcode() == Instruction::Or ||
|
||||
I1->getOpcode() == Instruction::Xor))
|
||||
if ((I1.getOperand(0) == I2->getOperand(1) &&
|
||||
I1.getOperand(1) == I2->getOperand(0)) &&
|
||||
(I1.getOpcode() == Instruction::Add ||
|
||||
I1.getOpcode() == Instruction::Mul ||
|
||||
I1.getOpcode() == Instruction::And ||
|
||||
I1.getOpcode() == Instruction::Or ||
|
||||
I1.getOpcode() == Instruction::Xor))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GCSE::visitBinaryOperator(Instruction *I) {
|
||||
Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
|
||||
Function *F = I->getParent()->getParent();
|
||||
bool GCSE::visitBinaryOperator(Instruction &I) {
|
||||
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
||||
Function *F = I.getParent()->getParent();
|
||||
|
||||
for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end();
|
||||
UI != UE; ++UI)
|
||||
if (Instruction *Other = dyn_cast<Instruction>(*UI))
|
||||
// Check to see if this new binary operator is not I, but same operand...
|
||||
if (Other != I && isIdenticalBinaryInst(I, Other)) {
|
||||
if (Other != &I && isIdenticalBinaryInst(I, Other)) {
|
||||
// These instructions are identical. Handle the situation.
|
||||
CommonSubExpressionFound(I, Other);
|
||||
CommonSubExpressionFound(&I, Other);
|
||||
return true; // One instruction eliminated!
|
||||
}
|
||||
|
||||
|
@ -319,42 +312,42 @@ static bool IdenticalComplexInst(const Instruction *I1, const Instruction *I2) {
|
|||
std::equal(I1->op_begin(), I1->op_end(), I2->op_begin());
|
||||
}
|
||||
|
||||
bool GCSE::visitGetElementPtrInst(GetElementPtrInst *I) {
|
||||
Value *Op = I->getOperand(0);
|
||||
Function *F = I->getParent()->getParent();
|
||||
bool GCSE::visitGetElementPtrInst(GetElementPtrInst &I) {
|
||||
Value *Op = I.getOperand(0);
|
||||
Function *F = I.getParent()->getParent();
|
||||
|
||||
for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end();
|
||||
UI != UE; ++UI)
|
||||
if (GetElementPtrInst *Other = dyn_cast<GetElementPtrInst>(*UI))
|
||||
// Check to see if this new getelementptr is not I, but same operand...
|
||||
if (Other != I && IdenticalComplexInst(I, Other)) {
|
||||
if (Other != &I && IdenticalComplexInst(&I, Other)) {
|
||||
// These instructions are identical. Handle the situation.
|
||||
CommonSubExpressionFound(I, Other);
|
||||
CommonSubExpressionFound(&I, Other);
|
||||
return true; // One instruction eliminated!
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GCSE::visitLoadInst(LoadInst *LI) {
|
||||
Value *Op = LI->getOperand(0);
|
||||
Function *F = LI->getParent()->getParent();
|
||||
bool GCSE::visitLoadInst(LoadInst &LI) {
|
||||
Value *Op = LI.getOperand(0);
|
||||
Function *F = LI.getParent()->getParent();
|
||||
|
||||
for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end();
|
||||
UI != UE; ++UI)
|
||||
if (LoadInst *Other = dyn_cast<LoadInst>(*UI))
|
||||
// Check to see if this new load is not LI, but has the same operands...
|
||||
if (Other != LI && IdenticalComplexInst(LI, Other) &&
|
||||
TryToRemoveALoad(LI, Other))
|
||||
if (Other != &LI && IdenticalComplexInst(&LI, Other) &&
|
||||
TryToRemoveALoad(&LI, Other))
|
||||
return true; // An instruction was eliminated!
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool isInvalidatingInst(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::Store ||
|
||||
I->getOpcode() == Instruction::Call ||
|
||||
I->getOpcode() == Instruction::Invoke;
|
||||
static inline bool isInvalidatingInst(const Instruction &I) {
|
||||
return I.getOpcode() == Instruction::Store ||
|
||||
I.getOpcode() == Instruction::Call ||
|
||||
I.getOpcode() == Instruction::Invoke;
|
||||
}
|
||||
|
||||
// TryToRemoveALoad - Try to remove one of L1 or L2. The problem with removing
|
||||
|
@ -373,9 +366,7 @@ bool GCSE::TryToRemoveALoad(LoadInst *L1, LoadInst *L2) {
|
|||
|
||||
BasicBlock *BB1 = L1->getParent(), *BB2 = L2->getParent();
|
||||
|
||||
// FIXME: This is incredibly painful with broken rep
|
||||
BasicBlock::iterator L1I = std::find(BB1->begin(), BB1->end(), L1);
|
||||
assert(L1I != BB1->end() && "Inst not in own parent?");
|
||||
BasicBlock::iterator L1I = L1;
|
||||
|
||||
// L1 now dominates L2. Check to see if the intervening instructions between
|
||||
// the two loads include a store or call...
|
||||
|
@ -384,7 +375,7 @@ bool GCSE::TryToRemoveALoad(LoadInst *L1, LoadInst *L2) {
|
|||
// In this degenerate case, no checking of global basic blocks has to occur
|
||||
// just check the instructions BETWEEN L1 & L2...
|
||||
//
|
||||
for (++L1I; *L1I != L2; ++L1I)
|
||||
for (++L1I; &*L1I != L2; ++L1I)
|
||||
if (isInvalidatingInst(*L1I))
|
||||
return false; // Cannot eliminate load
|
||||
|
||||
|
@ -404,7 +395,7 @@ bool GCSE::TryToRemoveALoad(LoadInst *L1, LoadInst *L2) {
|
|||
// Make sure that there are no store instructions between the start of BB2
|
||||
// and the second load instruction...
|
||||
//
|
||||
for (BasicBlock::iterator II = BB2->begin(); *II != L2; ++II)
|
||||
for (BasicBlock::iterator II = BB2->begin(); &*II != L2; ++II)
|
||||
if (isInvalidatingInst(*II)) {
|
||||
BBContainsStore[BB2] = true;
|
||||
return false; // Cannot eliminate load
|
||||
|
|
|
@ -47,9 +47,10 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
|||
// info into a vector...
|
||||
//
|
||||
std::vector<InductionVariable> IndVars; // Induction variables for block
|
||||
for (BasicBlock::iterator I = Header->begin();
|
||||
PHINode *PN = dyn_cast<PHINode>(*I); ++I)
|
||||
BasicBlock::iterator AfterPHIIt = Header->begin();
|
||||
for (; PHINode *PN = dyn_cast<PHINode>(&*AfterPHIIt); ++AfterPHIIt)
|
||||
IndVars.push_back(InductionVariable(PN, Loops));
|
||||
// AfterPHIIt now points to first nonphi instruction...
|
||||
|
||||
// If there are no phi nodes in this basic block, there can't be indvars...
|
||||
if (IndVars.empty()) return Changed;
|
||||
|
@ -77,7 +78,7 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
|||
PHINode *PN = new PHINode(Type::UIntTy, "cann-indvar");
|
||||
|
||||
// Insert the phi node at the end of the other phi nodes...
|
||||
Header->getInstList().insert(Header->begin()+IndVars.size(), PN);
|
||||
AfterPHIIt = ++Header->getInstList().insert(AfterPHIIt, PN);
|
||||
|
||||
// Create the increment instruction to add one to the counter...
|
||||
Instruction *Add = BinaryOperator::create(Instruction::Add, PN,
|
||||
|
@ -85,7 +86,7 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
|||
"add1-indvar");
|
||||
|
||||
// Insert the add instruction after all of the PHI nodes...
|
||||
Header->getInstList().insert(Header->begin()+(IndVars.size()+1), Add);
|
||||
Header->getInstList().insert(AfterPHIIt, Add);
|
||||
|
||||
// Figure out which block is incoming and which is the backedge for the loop
|
||||
BasicBlock *Incoming, *BackEdgeBlock;
|
||||
|
@ -123,7 +124,6 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
|||
// Loop through and replace all of the auxillary induction variables with
|
||||
// references to the primary induction variable...
|
||||
//
|
||||
unsigned InsertPos = IndVars.size();
|
||||
for (unsigned i = 0; i < IndVars.size(); ++i) {
|
||||
InductionVariable *IV = &IndVars[i];
|
||||
|
||||
|
@ -139,12 +139,11 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
|||
|
||||
// If the types are not compatible, insert a cast now...
|
||||
if (Val->getType() != IV->Step->getType())
|
||||
Val = InsertCast(Val, IV->Step->getType(),
|
||||
Header->begin()+InsertPos++);
|
||||
Val = InsertCast(Val, IV->Step->getType(), AfterPHIIt);
|
||||
|
||||
Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step, Name);
|
||||
// Insert the phi node at the end of the other phi nodes...
|
||||
Header->getInstList().insert(Header->begin()+InsertPos++, Val);
|
||||
Header->getInstList().insert(AfterPHIIt, Val);
|
||||
}
|
||||
|
||||
if (!isa<Constant>(IV->Start) || // If the start != 0
|
||||
|
@ -154,18 +153,16 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
|||
|
||||
// If the types are not compatible, insert a cast now...
|
||||
if (Val->getType() != IV->Start->getType())
|
||||
Val = InsertCast(Val, IV->Start->getType(),
|
||||
Header->begin()+InsertPos++);
|
||||
Val = InsertCast(Val, IV->Start->getType(), AfterPHIIt);
|
||||
|
||||
Val = BinaryOperator::create(Instruction::Add, Val, IV->Start, Name);
|
||||
// Insert the phi node at the end of the other phi nodes...
|
||||
Header->getInstList().insert(Header->begin()+InsertPos++, Val);
|
||||
Header->getInstList().insert(AfterPHIIt, Val);
|
||||
}
|
||||
|
||||
// If the PHI node has a different type than val is, insert a cast now...
|
||||
if (Val->getType() != IV->Phi->getType())
|
||||
Val = InsertCast(Val, IV->Phi->getType(),
|
||||
Header->begin()+InsertPos++);
|
||||
Val = InsertCast(Val, IV->Phi->getType(), AfterPHIIt);
|
||||
|
||||
// Replace all uses of the old PHI node with the new computed value...
|
||||
IV->Phi->replaceAllUsesWith(Val);
|
||||
|
@ -176,9 +173,7 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
|||
Val->setName(OldName);
|
||||
|
||||
// Delete the old, now unused, phi node...
|
||||
Header->getInstList().remove(IV->Phi);
|
||||
delete IV->Phi;
|
||||
InsertPos--; // Deleted an instr, decrement insert position
|
||||
Header->getInstList().erase(IV->Phi);
|
||||
Changed = true;
|
||||
++NumRemoved;
|
||||
}
|
||||
|
@ -193,7 +188,7 @@ namespace {
|
|||
return "Induction Variable Cannonicalize";
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function *F) {
|
||||
virtual bool runOnFunction(Function &) {
|
||||
LoopInfo &LI = getAnalysis<LoopInfo>();
|
||||
|
||||
// Induction Variables live in the header nodes of loops
|
||||
|
|
|
@ -36,11 +36,11 @@ namespace {
|
|||
// Worklist of all of the instructions that need to be simplified.
|
||||
std::vector<Instruction*> WorkList;
|
||||
|
||||
void AddUsesToWorkList(Instruction *I) {
|
||||
void AddUsesToWorkList(Instruction &I) {
|
||||
// The instruction was simplified, add all users of the instruction to
|
||||
// the work lists because they might get more simplified now...
|
||||
//
|
||||
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
|
||||
for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
|
||||
UI != UE; ++UI)
|
||||
WorkList.push_back(cast<Instruction>(*UI));
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ namespace {
|
|||
public:
|
||||
const char *getPassName() const { return "Instruction Combining"; }
|
||||
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.preservesCFG();
|
||||
|
@ -61,37 +61,37 @@ namespace {
|
|||
// I - Change was made, I is still valid
|
||||
// otherwise - Change was made, replace I with returned instruction
|
||||
//
|
||||
Instruction *visitNot(UnaryOperator *I);
|
||||
Instruction *visitAdd(BinaryOperator *I);
|
||||
Instruction *visitSub(BinaryOperator *I);
|
||||
Instruction *visitMul(BinaryOperator *I);
|
||||
Instruction *visitDiv(BinaryOperator *I);
|
||||
Instruction *visitRem(BinaryOperator *I);
|
||||
Instruction *visitAnd(BinaryOperator *I);
|
||||
Instruction *visitOr (BinaryOperator *I);
|
||||
Instruction *visitXor(BinaryOperator *I);
|
||||
Instruction *visitSetCondInst(BinaryOperator *I);
|
||||
Instruction *visitShiftInst(Instruction *I);
|
||||
Instruction *visitCastInst(CastInst *CI);
|
||||
Instruction *visitPHINode(PHINode *PN);
|
||||
Instruction *visitGetElementPtrInst(GetElementPtrInst *GEP);
|
||||
Instruction *visitMemAccessInst(MemAccessInst *MAI);
|
||||
Instruction *visitNot(UnaryOperator &I);
|
||||
Instruction *visitAdd(BinaryOperator &I);
|
||||
Instruction *visitSub(BinaryOperator &I);
|
||||
Instruction *visitMul(BinaryOperator &I);
|
||||
Instruction *visitDiv(BinaryOperator &I);
|
||||
Instruction *visitRem(BinaryOperator &I);
|
||||
Instruction *visitAnd(BinaryOperator &I);
|
||||
Instruction *visitOr (BinaryOperator &I);
|
||||
Instruction *visitXor(BinaryOperator &I);
|
||||
Instruction *visitSetCondInst(BinaryOperator &I);
|
||||
Instruction *visitShiftInst(Instruction &I);
|
||||
Instruction *visitCastInst(CastInst &CI);
|
||||
Instruction *visitPHINode(PHINode &PN);
|
||||
Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);
|
||||
Instruction *visitMemAccessInst(MemAccessInst &MAI);
|
||||
|
||||
// visitInstruction - Specify what to return for unhandled instructions...
|
||||
Instruction *visitInstruction(Instruction *I) { return 0; }
|
||||
Instruction *visitInstruction(Instruction &I) { return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitNot(UnaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitNot(UnaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
|
||||
// not (not X) = X
|
||||
if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(0)))
|
||||
if (Instruction *Op = dyn_cast<Instruction>(I.getOperand(0)))
|
||||
if (Op->getOpcode() == Instruction::Not) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op->getOperand(0));
|
||||
return I;
|
||||
I.replaceAllUsesWith(Op->getOperand(0));
|
||||
return &I;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,9 +100,9 @@ Instruction *InstCombiner::visitNot(UnaryOperator *I) {
|
|||
// Make sure that this instruction has a constant on the right hand side if it
|
||||
// has any constant arguments. If not, fix it an return true.
|
||||
//
|
||||
static bool SimplifyBinOp(BinaryOperator *I) {
|
||||
if (isa<Constant>(I->getOperand(0)) && !isa<Constant>(I->getOperand(1)))
|
||||
return !I->swapOperands();
|
||||
static bool SimplifyBinOp(BinaryOperator &I) {
|
||||
if (isa<Constant>(I.getOperand(0)) && !isa<Constant>(I.getOperand(1)))
|
||||
return !I.swapOperands();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -118,16 +118,16 @@ static inline Value *dyn_castNegInst(Value *V) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead add instructions...
|
||||
Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead add instructions...
|
||||
bool Changed = SimplifyBinOp(I);
|
||||
Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
|
||||
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
|
||||
|
||||
// Eliminate 'add int %X, 0'
|
||||
if (RHS == Constant::getNullValue(I->getType())) {
|
||||
if (RHS == Constant::getNullValue(I.getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(LHS);
|
||||
return I;
|
||||
I.replaceAllUsesWith(LHS);
|
||||
return &I;
|
||||
}
|
||||
|
||||
// -A + B --> B - A
|
||||
|
@ -150,33 +150,33 @@ Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
|
|||
// %Z = add int %X, 2
|
||||
//
|
||||
if (Constant *Val = *Op2 + *cast<Constant>(ILHS->getOperand(1))) {
|
||||
I->setOperand(0, ILHS->getOperand(0));
|
||||
I->setOperand(1, Val);
|
||||
return I;
|
||||
I.setOperand(0, ILHS->getOperand(0));
|
||||
I.setOperand(1, Val);
|
||||
return &I;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Changed ? I : 0;
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::visitSub(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead add instructions...
|
||||
Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
|
||||
Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead add instructions...
|
||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||
|
||||
if (Op0 == Op1) { // sub X, X -> 0
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
|
||||
return I;
|
||||
I.replaceAllUsesWith(Constant::getNullValue(I.getType()));
|
||||
return &I;
|
||||
}
|
||||
|
||||
// If this is a subtract instruction with a constant RHS, convert it to an add
|
||||
// instruction of a negative constant
|
||||
//
|
||||
if (Constant *Op2 = dyn_cast<Constant>(Op1))
|
||||
if (Constant *RHS = *Constant::getNullValue(I->getType()) - *Op2) // 0 - RHS
|
||||
return BinaryOperator::create(Instruction::Add, Op0, RHS, I->getName());
|
||||
if (Constant *RHS = *Constant::getNullValue(I.getType()) - *Op2) // 0 - RHS
|
||||
return BinaryOperator::create(Instruction::Add, Op0, RHS, I.getName());
|
||||
|
||||
// If this is a 'C = x-B', check to see if 'B = -A', so that C = x+A...
|
||||
if (Value *V = dyn_castNegInst(Op1))
|
||||
|
@ -198,59 +198,59 @@ Instruction *InstCombiner::visitSub(BinaryOperator *I) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::visitMul(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
bool Changed = SimplifyBinOp(I);
|
||||
Value *Op1 = I->getOperand(0);
|
||||
Value *Op1 = I.getOperand(0);
|
||||
|
||||
// Simplify add instructions with a constant RHS...
|
||||
if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1))) {
|
||||
if (I->getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(1)){
|
||||
if (Constant *Op2 = dyn_cast<Constant>(I.getOperand(1))) {
|
||||
if (I.getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(1)){
|
||||
// Eliminate 'mul int %X, 1'
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op1);
|
||||
return I;
|
||||
I.replaceAllUsesWith(Op1);
|
||||
return &I;
|
||||
|
||||
} else if (I->getType()->isIntegral() &&
|
||||
} else if (I.getType()->isIntegral() &&
|
||||
cast<ConstantInt>(Op2)->equalsInt(2)) {
|
||||
// Convert 'mul int %X, 2' to 'add int %X, %X'
|
||||
return BinaryOperator::create(Instruction::Add, Op1, Op1, I->getName());
|
||||
return BinaryOperator::create(Instruction::Add, Op1, Op1, I.getName());
|
||||
|
||||
} else if (Op2->isNullValue()) {
|
||||
// Eliminate 'mul int %X, 0'
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op2); // Set this value to zero directly
|
||||
return I;
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I.replaceAllUsesWith(Op2); // Set this value to zero directly
|
||||
return &I;
|
||||
}
|
||||
}
|
||||
|
||||
return Changed ? I : 0;
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitDiv(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
|
||||
// div X, 1 == X
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1)))
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1)))
|
||||
if (RHS->equalsInt(1)) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(I->getOperand(0));
|
||||
return I;
|
||||
I.replaceAllUsesWith(I.getOperand(0));
|
||||
return &I;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitRem(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
|
||||
// rem X, 1 == 0
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1)))
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1)))
|
||||
if (RHS->equalsInt(1)) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
|
||||
return I;
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I.replaceAllUsesWith(Constant::getNullValue(I.getType()));
|
||||
return &I;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -273,123 +273,123 @@ static Constant *getMaxValue(const Type *Ty) {
|
|||
}
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitAnd(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
bool Changed = SimplifyBinOp(I);
|
||||
Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
|
||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||
|
||||
// and X, X = X and X, 0 == 0
|
||||
if (Op0 == Op1 || Op1 == Constant::getNullValue(I->getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op1);
|
||||
return I;
|
||||
if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I.replaceAllUsesWith(Op1);
|
||||
return &I;
|
||||
}
|
||||
|
||||
// and X, -1 == X
|
||||
if (Constant *RHS = dyn_cast<Constant>(Op1))
|
||||
if (RHS == getMaxValue(I->getType())) {
|
||||
if (RHS == getMaxValue(I.getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op0);
|
||||
return I;
|
||||
I.replaceAllUsesWith(Op0);
|
||||
return &I;
|
||||
}
|
||||
|
||||
return Changed ? I : 0;
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitOr(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
bool Changed = SimplifyBinOp(I);
|
||||
Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
|
||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||
|
||||
// or X, X = X or X, 0 == X
|
||||
if (Op0 == Op1 || Op1 == Constant::getNullValue(I->getType())) {
|
||||
if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op0);
|
||||
return I;
|
||||
I.replaceAllUsesWith(Op0);
|
||||
return &I;
|
||||
}
|
||||
|
||||
// or X, -1 == -1
|
||||
if (Constant *RHS = dyn_cast<Constant>(Op1))
|
||||
if (RHS == getMaxValue(I->getType())) {
|
||||
if (RHS == getMaxValue(I.getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op1);
|
||||
return I;
|
||||
I.replaceAllUsesWith(Op1);
|
||||
return &I;
|
||||
}
|
||||
|
||||
return Changed ? I : 0;
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitXor(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
bool Changed = SimplifyBinOp(I);
|
||||
Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
|
||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||
|
||||
// xor X, X = 0
|
||||
if (Op0 == Op1) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
|
||||
return I;
|
||||
I.replaceAllUsesWith(Constant::getNullValue(I.getType()));
|
||||
return &I;
|
||||
}
|
||||
|
||||
// xor X, 0 == X
|
||||
if (Op1 == Constant::getNullValue(I->getType())) {
|
||||
if (Op1 == Constant::getNullValue(I.getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op0);
|
||||
return I;
|
||||
I.replaceAllUsesWith(Op0);
|
||||
return &I;
|
||||
}
|
||||
|
||||
return Changed ? I : 0;
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
// isTrueWhenEqual - Return true if the specified setcondinst instruction is
|
||||
// true when both operands are equal...
|
||||
//
|
||||
static bool isTrueWhenEqual(Instruction *I) {
|
||||
return I->getOpcode() == Instruction::SetEQ ||
|
||||
I->getOpcode() == Instruction::SetGE ||
|
||||
I->getOpcode() == Instruction::SetLE;
|
||||
static bool isTrueWhenEqual(Instruction &I) {
|
||||
return I.getOpcode() == Instruction::SetEQ ||
|
||||
I.getOpcode() == Instruction::SetGE ||
|
||||
I.getOpcode() == Instruction::SetLE;
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::visitSetCondInst(BinaryOperator *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
bool Changed = SimplifyBinOp(I);
|
||||
|
||||
// setcc X, X
|
||||
if (I->getOperand(0) == I->getOperand(1)) {
|
||||
if (I.getOperand(0) == I.getOperand(1)) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(ConstantBool::get(isTrueWhenEqual(I)));
|
||||
return I;
|
||||
I.replaceAllUsesWith(ConstantBool::get(isTrueWhenEqual(I)));
|
||||
return &I;
|
||||
}
|
||||
|
||||
// setcc <global*>, 0 - Global value addresses are never null!
|
||||
if (isa<GlobalValue>(I->getOperand(0)) &&
|
||||
isa<ConstantPointerNull>(I->getOperand(1))) {
|
||||
if (isa<GlobalValue>(I.getOperand(0)) &&
|
||||
isa<ConstantPointerNull>(I.getOperand(1))) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(ConstantBool::get(!isTrueWhenEqual(I)));
|
||||
return I;
|
||||
I.replaceAllUsesWith(ConstantBool::get(!isTrueWhenEqual(I)));
|
||||
return &I;
|
||||
}
|
||||
|
||||
return Changed ? I : 0;
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitShiftInst(Instruction *I) {
|
||||
if (I->use_empty()) return 0; // Don't fix dead instructions...
|
||||
assert(I->getOperand(1)->getType() == Type::UByteTy);
|
||||
Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
|
||||
Instruction *InstCombiner::visitShiftInst(Instruction &I) {
|
||||
if (I.use_empty()) return 0; // Don't fix dead instructions...
|
||||
assert(I.getOperand(1)->getType() == Type::UByteTy);
|
||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||
|
||||
// shl X, 0 == X and shr X, 0 == X
|
||||
// shl 0, X == 0 and shr 0, X == 0
|
||||
if (Op1 == Constant::getNullValue(Type::UByteTy) ||
|
||||
Op0 == Constant::getNullValue(Op0->getType())) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Op0);
|
||||
return I;
|
||||
I.replaceAllUsesWith(Op0);
|
||||
return &I;
|
||||
}
|
||||
|
||||
// shl int X, 32 = 0 and shr sbyte Y, 9 = 0, ... just don't eliminate shr of
|
||||
|
@ -398,10 +398,10 @@ Instruction *InstCombiner::visitShiftInst(Instruction *I) {
|
|||
if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
|
||||
unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
|
||||
if (CUI->getValue() >= TypeBits &&
|
||||
!(Op0->getType()->isSigned() && I->getOpcode() == Instruction::Shr)) {
|
||||
!(Op0->getType()->isSigned() && I.getOpcode() == Instruction::Shr)) {
|
||||
AddUsesToWorkList(I); // Add all modified instrs to worklist
|
||||
I->replaceAllUsesWith(Constant::getNullValue(Op0->getType()));
|
||||
return I;
|
||||
I.replaceAllUsesWith(Constant::getNullValue(Op0->getType()));
|
||||
return &I;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -411,12 +411,12 @@ Instruction *InstCombiner::visitShiftInst(Instruction *I) {
|
|||
// isEliminableCastOfCast - Return true if it is valid to eliminate the CI
|
||||
// instruction.
|
||||
//
|
||||
static inline bool isEliminableCastOfCast(const CastInst *CI,
|
||||
static inline bool isEliminableCastOfCast(const CastInst &CI,
|
||||
const CastInst *CSrc) {
|
||||
assert(CI->getOperand(0) == CSrc);
|
||||
assert(CI.getOperand(0) == CSrc);
|
||||
const Type *SrcTy = CSrc->getOperand(0)->getType();
|
||||
const Type *MidTy = CSrc->getType();
|
||||
const Type *DstTy = CI->getType();
|
||||
const Type *DstTy = CI.getType();
|
||||
|
||||
// It is legal to eliminate the instruction if casting A->B->A
|
||||
if (SrcTy == DstTy) return true;
|
||||
|
@ -437,27 +437,27 @@ static inline bool isEliminableCastOfCast(const CastInst *CI,
|
|||
|
||||
// CastInst simplification
|
||||
//
|
||||
Instruction *InstCombiner::visitCastInst(CastInst *CI) {
|
||||
if (CI->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitCastInst(CastInst &CI) {
|
||||
if (CI.use_empty()) return 0; // Don't fix dead instructions...
|
||||
|
||||
// If the user is casting a value to the same type, eliminate this cast
|
||||
// instruction...
|
||||
if (CI->getType() == CI->getOperand(0)->getType() && !CI->use_empty()) {
|
||||
if (CI.getType() == CI.getOperand(0)->getType() && !CI.use_empty()) {
|
||||
AddUsesToWorkList(CI); // Add all modified instrs to worklist
|
||||
CI->replaceAllUsesWith(CI->getOperand(0));
|
||||
return CI;
|
||||
CI.replaceAllUsesWith(CI.getOperand(0));
|
||||
return &CI;
|
||||
}
|
||||
|
||||
|
||||
// If casting the result of another cast instruction, try to eliminate this
|
||||
// one!
|
||||
//
|
||||
if (CastInst *CSrc = dyn_cast<CastInst>(CI->getOperand(0)))
|
||||
if (CastInst *CSrc = dyn_cast<CastInst>(CI.getOperand(0)))
|
||||
if (isEliminableCastOfCast(CI, CSrc)) {
|
||||
// This instruction now refers directly to the cast's src operand. This
|
||||
// has a good chance of making CSrc dead.
|
||||
CI->setOperand(0, CSrc->getOperand(0));
|
||||
return CI;
|
||||
CI.setOperand(0, CSrc->getOperand(0));
|
||||
return &CI;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -466,28 +466,28 @@ Instruction *InstCombiner::visitCastInst(CastInst *CI) {
|
|||
|
||||
// PHINode simplification
|
||||
//
|
||||
Instruction *InstCombiner::visitPHINode(PHINode *PN) {
|
||||
if (PN->use_empty()) return 0; // Don't fix dead instructions...
|
||||
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
||||
if (PN.use_empty()) return 0; // Don't fix dead instructions...
|
||||
|
||||
// If the PHI node only has one incoming value, eliminate the PHI node...
|
||||
if (PN->getNumIncomingValues() == 1) {
|
||||
if (PN.getNumIncomingValues() == 1) {
|
||||
AddUsesToWorkList(PN); // Add all modified instrs to worklist
|
||||
PN->replaceAllUsesWith(PN->getIncomingValue(0));
|
||||
return PN;
|
||||
PN.replaceAllUsesWith(PN.getIncomingValue(0));
|
||||
return &PN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst *GEP) {
|
||||
Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
// Is it getelementptr %P, uint 0
|
||||
// If so, elminate the noop.
|
||||
if (GEP->getNumOperands() == 2 && !GEP->use_empty() &&
|
||||
GEP->getOperand(1) == Constant::getNullValue(Type::UIntTy)) {
|
||||
// If so, eliminate the noop.
|
||||
if (GEP.getNumOperands() == 2 && !GEP.use_empty() &&
|
||||
GEP.getOperand(1) == Constant::getNullValue(Type::UIntTy)) {
|
||||
AddUsesToWorkList(GEP); // Add all modified instrs to worklist
|
||||
GEP->replaceAllUsesWith(GEP->getOperand(0));
|
||||
return GEP;
|
||||
GEP.replaceAllUsesWith(GEP.getOperand(0));
|
||||
return &GEP;
|
||||
}
|
||||
|
||||
return visitMemAccessInst(GEP);
|
||||
|
@ -498,36 +498,36 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst *GEP) {
|
|||
// getelementptr instruction, combine the indices of the GEP into this
|
||||
// instruction
|
||||
//
|
||||
Instruction *InstCombiner::visitMemAccessInst(MemAccessInst *MAI) {
|
||||
Instruction *InstCombiner::visitMemAccessInst(MemAccessInst &MAI) {
|
||||
GetElementPtrInst *Src =
|
||||
dyn_cast<GetElementPtrInst>(MAI->getPointerOperand());
|
||||
dyn_cast<GetElementPtrInst>(MAI.getPointerOperand());
|
||||
if (!Src) return 0;
|
||||
|
||||
std::vector<Value *> Indices;
|
||||
|
||||
// Only special case we have to watch out for is pointer arithmetic on the
|
||||
// 0th index of MAI.
|
||||
unsigned FirstIdx = MAI->getFirstIndexOperandNumber();
|
||||
if (FirstIdx == MAI->getNumOperands() ||
|
||||
(FirstIdx == MAI->getNumOperands()-1 &&
|
||||
MAI->getOperand(FirstIdx) == ConstantUInt::get(Type::UIntTy, 0))) {
|
||||
unsigned FirstIdx = MAI.getFirstIndexOperandNumber();
|
||||
if (FirstIdx == MAI.getNumOperands() ||
|
||||
(FirstIdx == MAI.getNumOperands()-1 &&
|
||||
MAI.getOperand(FirstIdx) == ConstantUInt::get(Type::UIntTy, 0))) {
|
||||
// Replace the index list on this MAI with the index on the getelementptr
|
||||
Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
|
||||
} else if (*MAI->idx_begin() == ConstantUInt::get(Type::UIntTy, 0)) {
|
||||
} else if (*MAI.idx_begin() == ConstantUInt::get(Type::UIntTy, 0)) {
|
||||
// Otherwise we can do the fold if the first index of the GEP is a zero
|
||||
Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
|
||||
Indices.insert(Indices.end(), MAI->idx_begin()+1, MAI->idx_end());
|
||||
Indices.insert(Indices.end(), MAI.idx_begin()+1, MAI.idx_end());
|
||||
}
|
||||
|
||||
if (Indices.empty()) return 0; // Can't do the fold?
|
||||
|
||||
switch (MAI->getOpcode()) {
|
||||
switch (MAI.getOpcode()) {
|
||||
case Instruction::GetElementPtr:
|
||||
return new GetElementPtrInst(Src->getOperand(0), Indices, MAI->getName());
|
||||
return new GetElementPtrInst(Src->getOperand(0), Indices, MAI.getName());
|
||||
case Instruction::Load:
|
||||
return new LoadInst(Src->getOperand(0), Indices, MAI->getName());
|
||||
return new LoadInst(Src->getOperand(0), Indices, MAI.getName());
|
||||
case Instruction::Store:
|
||||
return new StoreInst(MAI->getOperand(0), Src->getOperand(0), Indices);
|
||||
return new StoreInst(MAI.getOperand(0), Src->getOperand(0), Indices);
|
||||
default:
|
||||
assert(0 && "Unknown memaccessinst!");
|
||||
break;
|
||||
|
@ -537,7 +537,7 @@ Instruction *InstCombiner::visitMemAccessInst(MemAccessInst *MAI) {
|
|||
}
|
||||
|
||||
|
||||
bool InstCombiner::runOnFunction(Function *F) {
|
||||
bool InstCombiner::runOnFunction(Function &F) {
|
||||
bool Changed = false;
|
||||
|
||||
WorkList.insert(WorkList.end(), inst_begin(F), inst_end(F));
|
||||
|
@ -547,7 +547,7 @@ bool InstCombiner::runOnFunction(Function *F) {
|
|||
WorkList.pop_back();
|
||||
|
||||
// Now that we have an instruction, try combining it to simplify it...
|
||||
Instruction *Result = visit(I);
|
||||
Instruction *Result = visit(*I);
|
||||
if (Result) {
|
||||
++NumCombined;
|
||||
// Should we replace the old instruction with a new one?
|
||||
|
@ -562,10 +562,16 @@ bool InstCombiner::runOnFunction(Function *F) {
|
|||
}
|
||||
|
||||
ReplaceInstWithInst(I, Result);
|
||||
} else {
|
||||
// FIXME:
|
||||
// FIXME:
|
||||
// FIXME: This should DCE the instruction to simplify the cases above.
|
||||
// FIXME:
|
||||
// FIXME:
|
||||
}
|
||||
|
||||
WorkList.push_back(Result);
|
||||
AddUsesToWorkList(Result);
|
||||
AddUsesToWorkList(*Result);
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace {
|
|||
struct LICM : public FunctionPass, public InstVisitor<LICM> {
|
||||
const char *getPassName() const { return "Loop Invariant Code Motion"; }
|
||||
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
// This transformation requires natural loop information...
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
|
@ -69,7 +69,7 @@ namespace {
|
|||
// hoist - When an instruction is found to only use loop invariant operands
|
||||
// that is safe to hoist, this instruction is called to do the dirty work.
|
||||
//
|
||||
void hoist(Instruction *I);
|
||||
void hoist(Instruction &I);
|
||||
|
||||
// isLoopInvariant - Return true if the specified value is loop invariant
|
||||
inline bool isLoopInvariant(Value *V) {
|
||||
|
@ -85,21 +85,21 @@ namespace {
|
|||
// the specified instruction types are hoisted.
|
||||
//
|
||||
friend class InstVisitor<LICM>;
|
||||
void visitUnaryOperator(Instruction *I) {
|
||||
if (isLoopInvariant(I->getOperand(0))) hoist(I);
|
||||
void visitUnaryOperator(Instruction &I) {
|
||||
if (isLoopInvariant(I.getOperand(0))) hoist(I);
|
||||
}
|
||||
void visitBinaryOperator(Instruction *I) {
|
||||
if (isLoopInvariant(I->getOperand(0)) &&isLoopInvariant(I->getOperand(1)))
|
||||
void visitBinaryOperator(Instruction &I) {
|
||||
if (isLoopInvariant(I.getOperand(0)) && isLoopInvariant(I.getOperand(1)))
|
||||
hoist(I);
|
||||
}
|
||||
|
||||
void visitCastInst(CastInst *I) { visitUnaryOperator((Instruction*)I); }
|
||||
void visitShiftInst(ShiftInst *I) { visitBinaryOperator((Instruction*)I); }
|
||||
void visitCastInst(CastInst &I) { visitUnaryOperator((Instruction&)I); }
|
||||
void visitShiftInst(ShiftInst &I) { visitBinaryOperator((Instruction&)I); }
|
||||
|
||||
void visitGetElementPtrInst(GetElementPtrInst *GEPI) {
|
||||
Instruction *I = (Instruction*)GEPI;
|
||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
||||
if (!isLoopInvariant(I->getOperand(i))) return;
|
||||
void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
|
||||
Instruction &I = (Instruction&)GEPI;
|
||||
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
||||
if (!isLoopInvariant(I.getOperand(i))) return;
|
||||
hoist(I);
|
||||
}
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ namespace {
|
|||
|
||||
Pass *createLICMPass() { return new LICM(); }
|
||||
|
||||
bool LICM::runOnFunction(Function *F) {
|
||||
bool LICM::runOnFunction(Function &) {
|
||||
// get our loop information...
|
||||
const std::vector<Loop*> &TopLevelLoops =
|
||||
getAnalysis<LoopInfo>().getTopLevelLoops();
|
||||
|
@ -177,30 +177,26 @@ void LICM::visitLoop(Loop *L) {
|
|||
}
|
||||
|
||||
void LICM::visitBasicBlock(BasicBlock *BB) {
|
||||
// This cannot use an iterator, because it might get invalidated when PHI
|
||||
// nodes are inserted!
|
||||
//
|
||||
for (unsigned i = 0; i < BB->size(); ) {
|
||||
visit(BB->begin()[i]);
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
|
||||
visit(*I);
|
||||
|
||||
BasicBlock::iterator It = BB->begin()+i;
|
||||
if (dceInstruction(It))
|
||||
if (dceInstruction(I))
|
||||
Changed = true;
|
||||
else
|
||||
++i;
|
||||
++I;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LICM::hoist(Instruction *Inst) {
|
||||
if (Inst->use_empty()) return; // Don't (re) hoist dead instructions!
|
||||
void LICM::hoist(Instruction &Inst) {
|
||||
if (Inst.use_empty()) return; // Don't (re) hoist dead instructions!
|
||||
//cerr << "Hoisting " << Inst;
|
||||
|
||||
BasicBlock *Header = CurLoop->getHeader();
|
||||
|
||||
// Old instruction will be removed, so take it's name...
|
||||
string InstName = Inst->getName();
|
||||
Inst->setName("");
|
||||
string InstName = Inst.getName();
|
||||
Inst.setName("");
|
||||
|
||||
// The common case is that we have a pre-header. Generate special case code
|
||||
// that is faster if that is the case.
|
||||
|
@ -209,21 +205,21 @@ void LICM::hoist(Instruction *Inst) {
|
|||
BasicBlock *Pred = LoopPreds[0];
|
||||
|
||||
// Create a new copy of the instruction, for insertion into Pred.
|
||||
Instruction *New = Inst->clone();
|
||||
Instruction *New = Inst.clone();
|
||||
New->setName(InstName);
|
||||
|
||||
// Insert the new node in Pred, before the terminator.
|
||||
Pred->getInstList().insert(Pred->end()-1, New);
|
||||
Pred->getInstList().insert(--Pred->end(), New);
|
||||
|
||||
// Kill the old instruction.
|
||||
Inst->replaceAllUsesWith(New);
|
||||
// Kill the old instruction...
|
||||
Inst.replaceAllUsesWith(New);
|
||||
++NumHoistedPH;
|
||||
|
||||
} else {
|
||||
// No loop pre-header, insert a PHI node into header to capture all of the
|
||||
// incoming versions of the value.
|
||||
//
|
||||
PHINode *LoopVal = new PHINode(Inst->getType(), InstName+".phi");
|
||||
PHINode *LoopVal = new PHINode(Inst.getType(), InstName+".phi");
|
||||
|
||||
// Insert the new PHI node into the loop header...
|
||||
Header->getInstList().push_front(LoopVal);
|
||||
|
@ -233,11 +229,11 @@ void LICM::hoist(Instruction *Inst) {
|
|||
BasicBlock *Pred = LoopPreds[i];
|
||||
|
||||
// Create a new copy of the instruction, for insertion into Pred.
|
||||
Instruction *New = Inst->clone();
|
||||
Instruction *New = Inst.clone();
|
||||
New->setName(InstName);
|
||||
|
||||
// Insert the new node in Pred, before the terminator.
|
||||
Pred->getInstList().insert(Pred->end()-1, New);
|
||||
Pred->getInstList().insert(--Pred->end(), New);
|
||||
|
||||
// Add the incoming value to the PHI node.
|
||||
LoopVal->addIncoming(New, Pred);
|
||||
|
@ -253,7 +249,7 @@ void LICM::hoist(Instruction *Inst) {
|
|||
// entire loop body. The old definition was defined _inside_ of the loop,
|
||||
// so the scope cannot extend outside of the loop, so we're ok.
|
||||
//
|
||||
Inst->replaceAllUsesWith(LoopVal);
|
||||
Inst.replaceAllUsesWith(LoopVal);
|
||||
++NumHoistedNPH;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,12 +40,12 @@ public:
|
|||
// doPassInitialization - For the lower allocations pass, this ensures that a
|
||||
// module contains a declaration for a malloc and a free function.
|
||||
//
|
||||
bool doInitialization(Module *M);
|
||||
bool doInitialization(Module &M);
|
||||
|
||||
// runOnBasicBlock - This method does the actual work of converting
|
||||
// instructions over, assuming that the pass has already been initialized.
|
||||
//
|
||||
bool runOnBasicBlock(BasicBlock *BB);
|
||||
bool runOnBasicBlock(BasicBlock &BB);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ Pass *createLowerAllocationsPass(const TargetData &TD) {
|
|||
//
|
||||
// This function is always successful.
|
||||
//
|
||||
bool LowerAllocations::doInitialization(Module *M) {
|
||||
bool LowerAllocations::doInitialization(Module &M) {
|
||||
const FunctionType *MallocType =
|
||||
FunctionType::get(PointerType::get(Type::SByteTy),
|
||||
vector<const Type*>(1, Type::UIntTy), false);
|
||||
|
@ -70,8 +70,8 @@ bool LowerAllocations::doInitialization(Module *M) {
|
|||
vector<const Type*>(1, PointerType::get(Type::SByteTy)),
|
||||
false);
|
||||
|
||||
MallocFunc = M->getOrInsertFunction("malloc", MallocType);
|
||||
FreeFunc = M->getOrInsertFunction("free" , FreeType);
|
||||
MallocFunc = M.getOrInsertFunction("malloc", MallocType);
|
||||
FreeFunc = M.getOrInsertFunction("free" , FreeType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -79,17 +79,18 @@ bool LowerAllocations::doInitialization(Module *M) {
|
|||
// runOnBasicBlock - This method does the actual work of converting
|
||||
// instructions over, assuming that the pass has already been initialized.
|
||||
//
|
||||
bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
|
||||
bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) {
|
||||
bool Changed = false;
|
||||
assert(MallocFunc && FreeFunc && BB && "Pass not initialized!");
|
||||
assert(MallocFunc && FreeFunc && "Pass not initialized!");
|
||||
|
||||
BasicBlock::InstListType &BBIL = BB.getInstList();
|
||||
|
||||
// Loop over all of the instructions, looking for malloc or free instructions
|
||||
for (unsigned i = 0; i != BB->size(); ++i) {
|
||||
BasicBlock::InstListType &BBIL = BB->getInstList();
|
||||
if (MallocInst *MI = dyn_cast<MallocInst>(*(BBIL.begin()+i))) {
|
||||
BBIL.remove(BBIL.begin()+i); // remove the malloc instr...
|
||||
|
||||
const Type *AllocTy = cast<PointerType>(MI->getType())->getElementType();
|
||||
for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
|
||||
if (MallocInst *MI = dyn_cast<MallocInst>(&*I)) {
|
||||
BBIL.remove(I); // remove the malloc instr...
|
||||
|
||||
const Type *AllocTy = MI->getType()->getElementType();
|
||||
|
||||
// Get the number of bytes to be allocated for one element of the
|
||||
// requested type...
|
||||
|
@ -103,35 +104,34 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
|
|||
// Multiply it by the array size if neccesary...
|
||||
MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
|
||||
MallocArg);
|
||||
BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
|
||||
I = ++BBIL.insert(I, cast<Instruction>(MallocArg));
|
||||
}
|
||||
|
||||
// Create the call to Malloc...
|
||||
CallInst *MCall = new CallInst(MallocFunc,
|
||||
vector<Value*>(1, MallocArg));
|
||||
BBIL.insert(BBIL.begin()+i, MCall);
|
||||
I = BBIL.insert(I, MCall);
|
||||
|
||||
// Create a cast instruction to convert to the right type...
|
||||
CastInst *MCast = new CastInst(MCall, MI->getType());
|
||||
BBIL.insert(BBIL.begin()+i+1, MCast);
|
||||
I = BBIL.insert(++I, MCast);
|
||||
|
||||
// Replace all uses of the old malloc inst with the cast inst
|
||||
MI->replaceAllUsesWith(MCast);
|
||||
delete MI; // Delete the malloc inst
|
||||
Changed = true;
|
||||
++NumLowered;
|
||||
} else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
|
||||
BBIL.remove(BB->getInstList().begin()+i);
|
||||
} else if (FreeInst *FI = dyn_cast<FreeInst>(&*I)) {
|
||||
BBIL.remove(I);
|
||||
|
||||
// Cast the argument to free into a ubyte*...
|
||||
CastInst *MCast = new CastInst(FI->getOperand(0),
|
||||
PointerType::get(Type::UByteTy));
|
||||
BBIL.insert(BBIL.begin()+i, MCast);
|
||||
I = ++BBIL.insert(I, MCast);
|
||||
|
||||
// Insert a call to the free function...
|
||||
CallInst *FCall = new CallInst(FreeFunc,
|
||||
vector<Value*>(1, MCast));
|
||||
BBIL.insert(BBIL.begin()+i+1, FCall);
|
||||
CallInst *FCall = new CallInst(FreeFunc, vector<Value*>(1, MCast));
|
||||
I = BBIL.insert(I, FCall);
|
||||
|
||||
// Delete the old free instruction
|
||||
delete FI;
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace {
|
|||
struct PiNodeInserter : public FunctionPass {
|
||||
const char *getPassName() const { return "Pi Node Insertion"; }
|
||||
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.preservesCFG();
|
||||
|
@ -61,11 +61,10 @@ namespace {
|
|||
Pass *createPiNodeInsertionPass() { return new PiNodeInserter(); }
|
||||
|
||||
|
||||
bool PiNodeInserter::runOnFunction(Function *F) {
|
||||
bool PiNodeInserter::runOnFunction(Function &F) {
|
||||
bool Changed = false;
|
||||
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
|
||||
BasicBlock *BB = *I;
|
||||
TerminatorInst *TI = BB->getTerminator();
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
|
||||
TerminatorInst *TI = I->getTerminator();
|
||||
|
||||
// FIXME: Insert PI nodes for switch statements too
|
||||
|
||||
|
@ -112,8 +111,7 @@ bool PiNodeInserter::runOnFunction(Function *F) {
|
|||
}
|
||||
|
||||
|
||||
// alreadyHasPiNodeFor - Return true if there is already a Pi node in BB for
|
||||
// V.
|
||||
// alreadyHasPiNodeFor - Return true if there is already a Pi node in BB for V.
|
||||
static bool alreadyHasPiNodeFor(Value *V, BasicBlock *BB) {
|
||||
for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I)
|
||||
if (PHINode *PN = dyn_cast<PHINode>(*I))
|
||||
|
|
|
@ -39,13 +39,13 @@ namespace {
|
|||
return "Expression Reassociation";
|
||||
}
|
||||
|
||||
bool runOnFunction(Function *F);
|
||||
bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.preservesCFG();
|
||||
}
|
||||
private:
|
||||
void BuildRankMap(Function *F);
|
||||
void BuildRankMap(Function &F);
|
||||
unsigned getRank(Value *V);
|
||||
bool ReassociateExpr(BinaryOperator *I);
|
||||
bool ReassociateBB(BasicBlock *BB);
|
||||
|
@ -54,9 +54,9 @@ namespace {
|
|||
|
||||
Pass *createReassociatePass() { return new Reassociate(); }
|
||||
|
||||
void Reassociate::BuildRankMap(Function *F) {
|
||||
void Reassociate::BuildRankMap(Function &F) {
|
||||
unsigned i = 1;
|
||||
ReversePostOrderTraversal<Function*> RPOT(F);
|
||||
ReversePostOrderTraversal<Function*> RPOT(&F);
|
||||
for (ReversePostOrderTraversal<Function*>::rpo_iterator I = RPOT.begin(),
|
||||
E = RPOT.end(); I != E; ++I)
|
||||
RankMap[*I] = ++i;
|
||||
|
@ -182,15 +182,11 @@ static Value *NegateValue(Value *V, BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
// adding it now, we are assured that the neg instructions we just
|
||||
// inserted dominate the instruction we are about to insert after them.
|
||||
//
|
||||
BasicBlock::iterator NBI = BI;
|
||||
|
||||
// Scan through the inserted instructions, looking for RHS, which must be
|
||||
// after LHS in the instruction list.
|
||||
while (*NBI != RHS) ++NBI;
|
||||
BasicBlock::iterator NBI = cast<Instruction>(RHS);
|
||||
|
||||
Instruction *Add =
|
||||
BinaryOperator::create(Instruction::Add, LHS, RHS, I->getName()+".neg");
|
||||
BB->getInstList().insert(NBI+1, Add); // Add to the basic block...
|
||||
BB->getInstList().insert(++NBI, Add); // Add to the basic block...
|
||||
return Add;
|
||||
}
|
||||
|
||||
|
@ -209,12 +205,11 @@ static Value *NegateValue(Value *V, BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||
bool Reassociate::ReassociateBB(BasicBlock *BB) {
|
||||
bool Changed = false;
|
||||
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) {
|
||||
Instruction *Inst = *BI;
|
||||
|
||||
// If this instruction is a commutative binary operator, and the ranks of
|
||||
// the two operands are sorted incorrectly, fix it now.
|
||||
//
|
||||
if (BinaryOperator *I = isCommutativeOperator(Inst)) {
|
||||
if (BinaryOperator *I = isCommutativeOperator(BI)) {
|
||||
if (!I->use_empty()) {
|
||||
// Make sure that we don't have a tree-shaped computation. If we do,
|
||||
// linearize it. Convert (A+B)+(C+D) into ((A+B)+C)+D
|
||||
|
@ -245,22 +240,23 @@ bool Reassociate::ReassociateBB(BasicBlock *BB) {
|
|||
Changed |= ReassociateExpr(I);
|
||||
}
|
||||
|
||||
} else if (Inst->getOpcode() == Instruction::Sub &&
|
||||
Inst->getOperand(0) != Constant::getNullValue(Inst->getType())) {
|
||||
} else if (BI->getOpcode() == Instruction::Sub &&
|
||||
BI->getOperand(0) != Constant::getNullValue(BI->getType())) {
|
||||
// Convert a subtract into an add and a neg instruction... so that sub
|
||||
// instructions can be commuted with other add instructions...
|
||||
//
|
||||
Instruction *New = BinaryOperator::create(Instruction::Add,
|
||||
Inst->getOperand(0),
|
||||
Inst->getOperand(1),
|
||||
Inst->getName());
|
||||
Value *NegatedValue = Inst->getOperand(1);
|
||||
BI->getOperand(0),
|
||||
BI->getOperand(1),
|
||||
BI->getName());
|
||||
Value *NegatedValue = BI->getOperand(1);
|
||||
|
||||
// Everyone now refers to the add instruction...
|
||||
Inst->replaceAllUsesWith(New);
|
||||
BI->replaceAllUsesWith(New);
|
||||
|
||||
// Put the new add in the place of the subtract... deleting the subtract
|
||||
delete BB->getInstList().replaceWith(BI, New);
|
||||
BI = BB->getInstList().erase(BI);
|
||||
BI = ++BB->getInstList().insert(BI, New);
|
||||
|
||||
// Calculate the negative value of Operand 1 of the sub instruction...
|
||||
// and set it as the RHS of the add instruction we just made...
|
||||
|
@ -275,13 +271,13 @@ bool Reassociate::ReassociateBB(BasicBlock *BB) {
|
|||
}
|
||||
|
||||
|
||||
bool Reassociate::runOnFunction(Function *F) {
|
||||
bool Reassociate::runOnFunction(Function &F) {
|
||||
// Recalculate the rank map for F
|
||||
BuildRankMap(F);
|
||||
|
||||
bool Changed = false;
|
||||
for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
|
||||
Changed |= ReassociateBB(*FI);
|
||||
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
|
||||
Changed |= ReassociateBB(FI);
|
||||
|
||||
// We are done with the rank map...
|
||||
RankMap.clear();
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
// runOnFunction - Run the Sparse Conditional Constant Propogation algorithm,
|
||||
// and return true if the function was modified.
|
||||
//
|
||||
bool runOnFunction(Function *F);
|
||||
bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.preservesCFG();
|
||||
|
@ -167,7 +167,7 @@ private:
|
|||
//
|
||||
void markExecutable(BasicBlock *BB) {
|
||||
if (BBExecutable.count(BB)) return;
|
||||
DEBUG(cerr << "Marking BB Executable: " << BB);
|
||||
DEBUG(cerr << "Marking BB Executable: " << *BB);
|
||||
BBExecutable.insert(BB); // Basic block is executable!
|
||||
BBWorkList.push_back(BB); // Add the block to the work list!
|
||||
}
|
||||
|
@ -177,35 +177,35 @@ private:
|
|||
// operand made a transition, or the instruction is newly executable. Change
|
||||
// the value type of I to reflect these changes if appropriate.
|
||||
//
|
||||
void visitPHINode(PHINode *I);
|
||||
void visitPHINode(PHINode &I);
|
||||
|
||||
// Terminators
|
||||
void visitReturnInst(ReturnInst *I) { /*does not have an effect*/ }
|
||||
void visitTerminatorInst(TerminatorInst *TI);
|
||||
void visitReturnInst(ReturnInst &I) { /*does not have an effect*/ }
|
||||
void visitTerminatorInst(TerminatorInst &TI);
|
||||
|
||||
void visitUnaryOperator(Instruction *I);
|
||||
void visitCastInst(CastInst *I) { visitUnaryOperator(I); }
|
||||
void visitBinaryOperator(Instruction *I);
|
||||
void visitShiftInst(ShiftInst *I) { visitBinaryOperator(I); }
|
||||
void visitUnaryOperator(Instruction &I);
|
||||
void visitCastInst(CastInst &I) { visitUnaryOperator(I); }
|
||||
void visitBinaryOperator(Instruction &I);
|
||||
void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
|
||||
|
||||
// Instructions that cannot be folded away...
|
||||
void visitStoreInst (Instruction *I) { /*returns void*/ }
|
||||
void visitMemAccessInst (Instruction *I) { markOverdefined(I); }
|
||||
void visitCallInst (Instruction *I) { markOverdefined(I); }
|
||||
void visitInvokeInst (Instruction *I) { markOverdefined(I); }
|
||||
void visitAllocationInst(Instruction *I) { markOverdefined(I); }
|
||||
void visitFreeInst (Instruction *I) { /*returns void*/ }
|
||||
void visitStoreInst (Instruction &I) { /*returns void*/ }
|
||||
void visitMemAccessInst (Instruction &I) { markOverdefined(&I); }
|
||||
void visitCallInst (Instruction &I) { markOverdefined(&I); }
|
||||
void visitInvokeInst (Instruction &I) { markOverdefined(&I); }
|
||||
void visitAllocationInst(Instruction &I) { markOverdefined(&I); }
|
||||
void visitFreeInst (Instruction &I) { /*returns void*/ }
|
||||
|
||||
void visitInstruction(Instruction *I) {
|
||||
void visitInstruction(Instruction &I) {
|
||||
// If a new instruction is added to LLVM that we don't handle...
|
||||
cerr << "SCCP: Don't know how to handle: " << I;
|
||||
markOverdefined(I); // Just in case
|
||||
markOverdefined(&I); // Just in case
|
||||
}
|
||||
|
||||
// getFeasibleSuccessors - Return a vector of booleans to indicate which
|
||||
// successors are reachable from a given terminator instruction.
|
||||
//
|
||||
void getFeasibleSuccessors(TerminatorInst *I, std::vector<bool> &Succs);
|
||||
void getFeasibleSuccessors(TerminatorInst &TI, std::vector<bool> &Succs);
|
||||
|
||||
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
|
||||
// block to the 'To' basic block is currently feasible...
|
||||
|
@ -218,8 +218,8 @@ private:
|
|||
//
|
||||
void OperandChangedState(User *U) {
|
||||
// Only instructions use other variable values!
|
||||
Instruction *I = cast<Instruction>(U);
|
||||
if (!BBExecutable.count(I->getParent())) return;// Inst not executable yet!
|
||||
Instruction &I = cast<Instruction>(*U);
|
||||
if (!BBExecutable.count(I.getParent())) return;// Inst not executable yet!
|
||||
visit(I);
|
||||
}
|
||||
};
|
||||
|
@ -241,9 +241,9 @@ Pass *createSCCPPass() {
|
|||
// runOnFunction() - Run the Sparse Conditional Constant Propogation algorithm,
|
||||
// and return true if the function was modified.
|
||||
//
|
||||
bool SCCP::runOnFunction(Function *F) {
|
||||
bool SCCP::runOnFunction(Function &F) {
|
||||
// Mark the first block of the function as being executable...
|
||||
markExecutable(F->front());
|
||||
markExecutable(&F.front());
|
||||
|
||||
// Process the work lists until their are empty!
|
||||
while (!BBWorkList.empty() || !InstWorkList.empty()) {
|
||||
|
@ -284,8 +284,8 @@ bool SCCP::runOnFunction(Function *F) {
|
|||
}
|
||||
|
||||
if (DebugFlag) {
|
||||
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
|
||||
if (!BBExecutable.count(*I))
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
|
||||
if (!BBExecutable.count(I))
|
||||
cerr << "BasicBlock Dead:" << *I;
|
||||
}
|
||||
|
||||
|
@ -293,20 +293,19 @@ bool SCCP::runOnFunction(Function *F) {
|
|||
// constants if we have found them to be of constant values.
|
||||
//
|
||||
bool MadeChanges = false;
|
||||
for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) {
|
||||
BasicBlock *BB = *FI;
|
||||
for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB)
|
||||
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
|
||||
Instruction *Inst = *BI;
|
||||
InstVal &IV = ValueState[Inst];
|
||||
Instruction &Inst = *BI;
|
||||
InstVal &IV = ValueState[&Inst];
|
||||
if (IV.isConstant()) {
|
||||
Constant *Const = IV.getConstant();
|
||||
DEBUG(cerr << "Constant: " << Const << " = " << Inst);
|
||||
|
||||
// Replaces all of the uses of a variable with uses of the constant.
|
||||
Inst->replaceAllUsesWith(Const);
|
||||
Inst.replaceAllUsesWith(Const);
|
||||
|
||||
// Remove the operator from the list of definitions... and delete it.
|
||||
delete BB->getInstList().remove(BI);
|
||||
BI = BB->getInstList().erase(BI);
|
||||
|
||||
// Hey, we just changed something!
|
||||
MadeChanges = true;
|
||||
|
@ -315,7 +314,6 @@ bool SCCP::runOnFunction(Function *F) {
|
|||
++BI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset state so that the next invocation will have empty data structures
|
||||
BBExecutable.clear();
|
||||
|
@ -328,9 +326,9 @@ bool SCCP::runOnFunction(Function *F) {
|
|||
// getFeasibleSuccessors - Return a vector of booleans to indicate which
|
||||
// successors are reachable from a given terminator instruction.
|
||||
//
|
||||
void SCCP::getFeasibleSuccessors(TerminatorInst *TI, std::vector<bool> &Succs) {
|
||||
assert(Succs.size() == TI->getNumSuccessors() && "Succs vector wrong size!");
|
||||
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
|
||||
void SCCP::getFeasibleSuccessors(TerminatorInst &TI, std::vector<bool> &Succs) {
|
||||
assert(Succs.size() == TI.getNumSuccessors() && "Succs vector wrong size!");
|
||||
if (BranchInst *BI = dyn_cast<BranchInst>(&TI)) {
|
||||
if (BI->isUnconditional()) {
|
||||
Succs[0] = true;
|
||||
} else {
|
||||
|
@ -343,14 +341,14 @@ void SCCP::getFeasibleSuccessors(TerminatorInst *TI, std::vector<bool> &Succs) {
|
|||
Succs[BCValue.getConstant() == ConstantBool::False] = true;
|
||||
}
|
||||
}
|
||||
} else if (InvokeInst *II = dyn_cast<InvokeInst>(TI)) {
|
||||
} else if (InvokeInst *II = dyn_cast<InvokeInst>(&TI)) {
|
||||
// Invoke instructions successors are always executable.
|
||||
Succs[0] = Succs[1] = true;
|
||||
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
|
||||
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(&TI)) {
|
||||
InstVal &SCValue = getValueState(SI->getCondition());
|
||||
if (SCValue.isOverdefined()) { // Overdefined condition?
|
||||
// All destinations are executable!
|
||||
Succs.assign(TI->getNumSuccessors(), true);
|
||||
Succs.assign(TI.getNumSuccessors(), true);
|
||||
} else if (SCValue.isConstant()) {
|
||||
Constant *CPV = SCValue.getConstant();
|
||||
// Make sure to skip the "default value" which isn't a value
|
||||
|
@ -367,7 +365,7 @@ void SCCP::getFeasibleSuccessors(TerminatorInst *TI, std::vector<bool> &Succs) {
|
|||
}
|
||||
} else {
|
||||
cerr << "SCCP: Don't know how to handle: " << TI;
|
||||
Succs.assign(TI->getNumSuccessors(), true);
|
||||
Succs.assign(TI.getNumSuccessors(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +382,7 @@ bool SCCP::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
|
|||
// Check to make sure this edge itself is actually feasible now...
|
||||
TerminatorInst *FT = From->getTerminator();
|
||||
std::vector<bool> SuccFeasible(FT->getNumSuccessors());
|
||||
getFeasibleSuccessors(FT, SuccFeasible);
|
||||
getFeasibleSuccessors(*FT, SuccFeasible);
|
||||
|
||||
// Check all edges from From to To. If any are feasible, return true.
|
||||
for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
|
||||
|
@ -414,8 +412,8 @@ bool SCCP::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
|
|||
// successors executable.
|
||||
//
|
||||
|
||||
void SCCP::visitPHINode(PHINode *PN) {
|
||||
unsigned NumValues = PN->getNumIncomingValues(), i;
|
||||
void SCCP::visitPHINode(PHINode &PN) {
|
||||
unsigned NumValues = PN.getNumIncomingValues(), i;
|
||||
InstVal *OperandIV = 0;
|
||||
|
||||
// Look at all of the executable operands of the PHI node. If any of them
|
||||
|
@ -425,11 +423,11 @@ void SCCP::visitPHINode(PHINode *PN) {
|
|||
// If there are no executable operands, the PHI remains undefined.
|
||||
//
|
||||
for (i = 0; i < NumValues; ++i) {
|
||||
if (isEdgeFeasible(PN->getIncomingBlock(i), PN->getParent())) {
|
||||
InstVal &IV = getValueState(PN->getIncomingValue(i));
|
||||
if (isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) {
|
||||
InstVal &IV = getValueState(PN.getIncomingValue(i));
|
||||
if (IV.isUndefined()) continue; // Doesn't influence PHI node.
|
||||
if (IV.isOverdefined()) { // PHI node becomes overdefined!
|
||||
markOverdefined(PN);
|
||||
markOverdefined(&PN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -445,7 +443,7 @@ void SCCP::visitPHINode(PHINode *PN) {
|
|||
// Yes there is. This means the PHI node is not constant.
|
||||
// You must be overdefined poor PHI.
|
||||
//
|
||||
markOverdefined(PN); // The PHI node now becomes overdefined
|
||||
markOverdefined(&PN); // The PHI node now becomes overdefined
|
||||
return; // I'm done analyzing you
|
||||
}
|
||||
}
|
||||
|
@ -459,18 +457,18 @@ void SCCP::visitPHINode(PHINode *PN) {
|
|||
//
|
||||
if (OperandIV) {
|
||||
assert(OperandIV->isConstant() && "Should only be here for constants!");
|
||||
markConstant(PN, OperandIV->getConstant()); // Aquire operand value
|
||||
markConstant(&PN, OperandIV->getConstant()); // Aquire operand value
|
||||
}
|
||||
}
|
||||
|
||||
void SCCP::visitTerminatorInst(TerminatorInst *TI) {
|
||||
std::vector<bool> SuccFeasible(TI->getNumSuccessors());
|
||||
void SCCP::visitTerminatorInst(TerminatorInst &TI) {
|
||||
std::vector<bool> SuccFeasible(TI.getNumSuccessors());
|
||||
getFeasibleSuccessors(TI, SuccFeasible);
|
||||
|
||||
// Mark all feasible successors executable...
|
||||
for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
|
||||
if (SuccFeasible[i]) {
|
||||
BasicBlock *Succ = TI->getSuccessor(i);
|
||||
BasicBlock *Succ = TI.getSuccessor(i);
|
||||
markExecutable(Succ);
|
||||
|
||||
// Visit all of the PHI nodes that merge values from this block...
|
||||
|
@ -478,49 +476,49 @@ void SCCP::visitTerminatorInst(TerminatorInst *TI) {
|
|||
// constant now may not be.
|
||||
//
|
||||
for (BasicBlock::iterator I = Succ->begin();
|
||||
PHINode *PN = dyn_cast<PHINode>(*I); ++I)
|
||||
visitPHINode(PN);
|
||||
PHINode *PN = dyn_cast<PHINode>(&*I); ++I)
|
||||
visitPHINode(*PN);
|
||||
}
|
||||
}
|
||||
|
||||
void SCCP::visitUnaryOperator(Instruction *I) {
|
||||
Value *V = I->getOperand(0);
|
||||
void SCCP::visitUnaryOperator(Instruction &I) {
|
||||
Value *V = I.getOperand(0);
|
||||
InstVal &VState = getValueState(V);
|
||||
if (VState.isOverdefined()) { // Inherit overdefinedness of operand
|
||||
markOverdefined(I);
|
||||
markOverdefined(&I);
|
||||
} else if (VState.isConstant()) { // Propogate constant value
|
||||
Constant *Result = isa<CastInst>(I)
|
||||
? ConstantFoldCastInstruction(VState.getConstant(), I->getType())
|
||||
: ConstantFoldUnaryInstruction(I->getOpcode(), VState.getConstant());
|
||||
? ConstantFoldCastInstruction(VState.getConstant(), I.getType())
|
||||
: ConstantFoldUnaryInstruction(I.getOpcode(), VState.getConstant());
|
||||
|
||||
if (Result) {
|
||||
// This instruction constant folds!
|
||||
markConstant(I, Result);
|
||||
markConstant(&I, Result);
|
||||
} else {
|
||||
markOverdefined(I); // Don't know how to fold this instruction. :(
|
||||
markOverdefined(&I); // Don't know how to fold this instruction. :(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle BinaryOperators and Shift Instructions...
|
||||
void SCCP::visitBinaryOperator(Instruction *I) {
|
||||
InstVal &V1State = getValueState(I->getOperand(0));
|
||||
InstVal &V2State = getValueState(I->getOperand(1));
|
||||
void SCCP::visitBinaryOperator(Instruction &I) {
|
||||
InstVal &V1State = getValueState(I.getOperand(0));
|
||||
InstVal &V2State = getValueState(I.getOperand(1));
|
||||
if (V1State.isOverdefined() || V2State.isOverdefined()) {
|
||||
markOverdefined(I);
|
||||
markOverdefined(&I);
|
||||
} else if (V1State.isConstant() && V2State.isConstant()) {
|
||||
Constant *Result = 0;
|
||||
if (isa<BinaryOperator>(I))
|
||||
Result = ConstantFoldBinaryInstruction(I->getOpcode(),
|
||||
Result = ConstantFoldBinaryInstruction(I.getOpcode(),
|
||||
V1State.getConstant(),
|
||||
V2State.getConstant());
|
||||
else if (isa<ShiftInst>(I))
|
||||
Result = ConstantFoldShiftInstruction(I->getOpcode(),
|
||||
Result = ConstantFoldShiftInstruction(I.getOpcode(),
|
||||
V1State.getConstant(),
|
||||
V2State.getConstant());
|
||||
if (Result)
|
||||
markConstant(I, Result); // This instruction constant folds!
|
||||
markConstant(&I, Result); // This instruction constant folds!
|
||||
else
|
||||
markOverdefined(I); // Don't know how to fold this instruction. :(
|
||||
markOverdefined(&I); // Don't know how to fold this instruction. :(
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace {
|
|||
struct CFGSimplifyPass : public FunctionPass {
|
||||
const char *getPassName() const { return "Simplify CFG"; }
|
||||
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,29 +49,28 @@ static bool MarkAliveBlocks(BasicBlock *BB, std::set<BasicBlock*> &Reachable) {
|
|||
// It is possible that we may require multiple passes over the code to fully
|
||||
// simplify the CFG.
|
||||
//
|
||||
bool CFGSimplifyPass::runOnFunction(Function *F) {
|
||||
bool CFGSimplifyPass::runOnFunction(Function &F) {
|
||||
std::set<BasicBlock*> Reachable;
|
||||
bool Changed = MarkAliveBlocks(F->front(), Reachable);
|
||||
bool Changed = MarkAliveBlocks(F.begin(), Reachable);
|
||||
|
||||
// If there are unreachable blocks in the CFG...
|
||||
if (Reachable.size() != F->size()) {
|
||||
assert(Reachable.size() < F->size());
|
||||
NumSimpl += F->size()-Reachable.size();
|
||||
if (Reachable.size() != F.size()) {
|
||||
assert(Reachable.size() < F.size());
|
||||
NumSimpl += F.size()-Reachable.size();
|
||||
|
||||
// Loop over all of the basic blocks that are not reachable, dropping all of
|
||||
// their internal references...
|
||||
for (Function::iterator I = F->begin()+1, E = F->end(); I != E; ++I)
|
||||
if (!Reachable.count(*I)) {
|
||||
BasicBlock *BB = *I;
|
||||
for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB)
|
||||
if (!Reachable.count(BB)) {
|
||||
for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI!=SE; ++SI)
|
||||
if (Reachable.count(*SI))
|
||||
(*SI)->removePredecessor(BB);
|
||||
BB->dropAllReferences();
|
||||
}
|
||||
|
||||
for (Function::iterator I = F->begin()+1; I != F->end();)
|
||||
if (!Reachable.count(*I))
|
||||
delete F->getBasicBlocks().remove(I);
|
||||
for (Function::iterator I = ++F.begin(); I != F.end();)
|
||||
if (!Reachable.count(I))
|
||||
I = F.getBasicBlockList().erase(I);
|
||||
else
|
||||
++I;
|
||||
|
||||
|
@ -85,12 +84,10 @@ bool CFGSimplifyPass::runOnFunction(Function *F) {
|
|||
// Loop over all of the basic blocks (except the first one) and remove them
|
||||
// if they are unneeded...
|
||||
//
|
||||
for (Function::iterator BBIt = F->begin()+1; BBIt != F->end(); ) {
|
||||
if (SimplifyCFG(BBIt)) {
|
||||
for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
|
||||
if (SimplifyCFG(BBIt++)) {
|
||||
LocalChange = true;
|
||||
++NumSimpl;
|
||||
} else {
|
||||
++BBIt;
|
||||
}
|
||||
}
|
||||
Changed |= LocalChange;
|
||||
|
|
|
@ -42,29 +42,12 @@ static bool StripSymbolTable(SymbolTable *SymTab) {
|
|||
return RemovedSymbol;
|
||||
}
|
||||
|
||||
|
||||
// DoSymbolStripping - Remove all symbolic information from a function
|
||||
//
|
||||
static bool doSymbolStripping(Function *F) {
|
||||
return StripSymbolTable(F->getSymbolTable());
|
||||
}
|
||||
|
||||
// doStripGlobalSymbols - Remove all symbolic information from all functions
|
||||
// in a module, and all module level symbols. (function names, etc...)
|
||||
//
|
||||
static bool doStripGlobalSymbols(Module *M) {
|
||||
// Remove all symbols from functions in this module... and then strip all of
|
||||
// the symbols in this module...
|
||||
//
|
||||
return StripSymbolTable(M->getSymbolTable());
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct SymbolStripping : public FunctionPass {
|
||||
const char *getPassName() const { return "Strip Symbols from Functions"; }
|
||||
|
||||
virtual bool runOnFunction(Function *F) {
|
||||
return doSymbolStripping(F);
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
return StripSymbolTable(F.getSymbolTable());
|
||||
}
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
|
@ -73,8 +56,8 @@ namespace {
|
|||
|
||||
struct FullSymbolStripping : public SymbolStripping {
|
||||
const char *getPassName() const { return "Strip Symbols from Module"; }
|
||||
virtual bool doInitialization(Module *M) {
|
||||
return doStripGlobalSymbols(M);
|
||||
virtual bool doInitialization(Module &M) {
|
||||
return StripSymbolTable(M.getSymbolTable());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -140,12 +140,12 @@ const Type *ConvertableToGEP(const Type *Ty, Value *OffsetVal,
|
|||
Offset -= Index*ElSize; // Consume part of the offset
|
||||
|
||||
if (BI) { // Generate code?
|
||||
BasicBlock *BB = (**BI)->getParent();
|
||||
BasicBlock *BB = (*BI)->getParent();
|
||||
if (Expr.Var->getType() != Type::UIntTy) {
|
||||
CastInst *IdxCast = new CastInst(Expr.Var, Type::UIntTy);
|
||||
if (Expr.Var->hasName())
|
||||
IdxCast->setName(Expr.Var->getName()+"-idxcast");
|
||||
*BI = BB->getInstList().insert(*BI, IdxCast)+1;
|
||||
*BI = ++BB->getInstList().insert(*BI, IdxCast);
|
||||
Expr.Var = IdxCast;
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ const Type *ConvertableToGEP(const Type *Ty, Value *OffsetVal,
|
|||
if (Expr.Var->hasName())
|
||||
Scaler->setName(Expr.Var->getName()+"-scale");
|
||||
|
||||
*BI = BB->getInstList().insert(*BI, Scaler)+1;
|
||||
*BI = ++BB->getInstList().insert(*BI, Scaler);
|
||||
Expr.Var = Scaler;
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ const Type *ConvertableToGEP(const Type *Ty, Value *OffsetVal,
|
|||
Expr.Var, IndexAmt);
|
||||
if (Expr.Var->hasName())
|
||||
Offseter->setName(Expr.Var->getName()+"-offset");
|
||||
*BI = BB->getInstList().insert(*BI, Offseter)+1;
|
||||
*BI = ++BB->getInstList().insert(*BI, Offseter);
|
||||
Expr.Var = Offseter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace {
|
|||
// runOnFunction - To run this pass, first we calculate the alloca
|
||||
// instructions that are safe for promotion, then we promote each one.
|
||||
//
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
// getAnalysisUsage - We need dominance frontiers
|
||||
//
|
||||
|
@ -65,7 +65,7 @@ namespace {
|
|||
void Traverse(BasicBlock *BB, BasicBlock *Pred, vector<Value*> &IncVals,
|
||||
set<BasicBlock*> &Visited);
|
||||
bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx);
|
||||
void FindSafeAllocas(Function *F);
|
||||
void FindSafeAllocas(Function &F);
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
@ -102,12 +102,12 @@ static inline bool isSafeAlloca(const AllocaInst *AI) {
|
|||
|
||||
// FindSafeAllocas - Find allocas that are safe to promote
|
||||
//
|
||||
void PromotePass::FindSafeAllocas(Function *F) {
|
||||
BasicBlock *BB = F->getEntryNode(); // Get the entry node for the function
|
||||
void PromotePass::FindSafeAllocas(Function &F) {
|
||||
BasicBlock &BB = F.getEntryNode(); // Get the entry node for the function
|
||||
|
||||
// Look at all instructions in the entry node
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(*I)) // Is it an alloca?
|
||||
for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
|
||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(&*I)) // Is it an alloca?
|
||||
if (isSafeAlloca(AI)) { // If safe alloca, add alloca to safe list
|
||||
AllocaLookup[AI] = Allocas.size(); // Keep reverse mapping
|
||||
Allocas.push_back(AI);
|
||||
|
@ -116,7 +116,7 @@ void PromotePass::FindSafeAllocas(Function *F) {
|
|||
|
||||
|
||||
|
||||
bool PromotePass::runOnFunction(Function *F) {
|
||||
bool PromotePass::runOnFunction(Function &F) {
|
||||
// Calculate the set of safe allocas
|
||||
FindSafeAllocas(F);
|
||||
|
||||
|
@ -178,7 +178,7 @@ bool PromotePass::runOnFunction(Function *F) {
|
|||
// and inserting the phi nodes we marked as necessary
|
||||
//
|
||||
set<BasicBlock*> Visited; // The basic blocks we've already visited
|
||||
Traverse(F->front(), 0, Values, Visited);
|
||||
Traverse(F.begin(), 0, Values, Visited);
|
||||
|
||||
// Remove all instructions marked by being placed in the KillList...
|
||||
//
|
||||
|
@ -186,8 +186,7 @@ bool PromotePass::runOnFunction(Function *F) {
|
|||
Instruction *I = KillList.back();
|
||||
KillList.pop_back();
|
||||
|
||||
I->getParent()->getInstList().remove(I);
|
||||
delete I;
|
||||
I->getParent()->getInstList().erase(I);
|
||||
}
|
||||
|
||||
NumPromoted += Allocas.size();
|
||||
|
@ -248,7 +247,7 @@ void PromotePass::Traverse(BasicBlock *BB, BasicBlock *Pred,
|
|||
|
||||
// keep track of the value of each variable we're watching.. how?
|
||||
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II) {
|
||||
Instruction *I = *II; //get the instruction
|
||||
Instruction *I = II; // get the instruction
|
||||
|
||||
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
||||
Value *Ptr = LI->getPointerOperand();
|
||||
|
|
|
@ -13,16 +13,12 @@
|
|||
#include "llvm/SlotCalculator.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/iMemory.h"
|
||||
#include "llvm/iTerminators.h"
|
||||
#include "llvm/iPHINode.h"
|
||||
#include "llvm/iOther.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/Argument.h"
|
||||
#include "Support/StringExtras.h"
|
||||
#include "Support/STLExtras.h"
|
||||
#include <algorithm>
|
||||
|
@ -317,7 +313,7 @@ static void WriteConstantInt(ostream &Out, const Constant *CV, bool PrintName,
|
|||
} else if (isa<ConstantPointerNull>(CV)) {
|
||||
Out << "null";
|
||||
|
||||
} else if (ConstantPointerRef *PR = dyn_cast<ConstantPointerRef>(CV)) {
|
||||
} else if (const ConstantPointerRef *PR = dyn_cast<ConstantPointerRef>(CV)) {
|
||||
const GlobalValue *V = PR->getValue();
|
||||
if (V->hasName()) {
|
||||
Out << "%" << V->getName();
|
||||
|
@ -414,7 +410,7 @@ public:
|
|||
inline void write(const GlobalVariable *G) { printGlobal(G); }
|
||||
inline void write(const Function *F) { printFunction(F); }
|
||||
inline void write(const BasicBlock *BB) { printBasicBlock(BB); }
|
||||
inline void write(const Instruction *I) { printInstruction(I); }
|
||||
inline void write(const Instruction *I) { printInstruction(*I); }
|
||||
inline void write(const Constant *CPV) { printConstant(CPV); }
|
||||
inline void write(const Type *Ty) { printType(Ty); }
|
||||
|
||||
|
@ -428,7 +424,7 @@ private :
|
|||
void printFunction(const Function *F);
|
||||
void printArgument(const Argument *FA);
|
||||
void printBasicBlock(const BasicBlock *BB);
|
||||
void printInstruction(const Instruction *I);
|
||||
void printInstruction(const Instruction &I);
|
||||
|
||||
// printType - Go to extreme measures to attempt to print out a short,
|
||||
// symbolic version of a type name.
|
||||
|
@ -444,7 +440,7 @@ private :
|
|||
|
||||
// printInfoComment - Print a little comment after the instruction indicating
|
||||
// which slot it occupies.
|
||||
void printInfoComment(const Value *V);
|
||||
void printInfoComment(const Value &V);
|
||||
};
|
||||
|
||||
|
||||
|
@ -452,7 +448,7 @@ private :
|
|||
// without considering any symbolic types that we may have equal to it.
|
||||
//
|
||||
ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
|
||||
if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
|
||||
if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
|
||||
printType(FTy->getReturnType()) << " (";
|
||||
for (FunctionType::ParamTypes::const_iterator
|
||||
I = FTy->getParamTypes().begin(),
|
||||
|
@ -466,7 +462,7 @@ ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
|
|||
Out << "...";
|
||||
}
|
||||
Out << ")";
|
||||
} else if (StructType *STy = dyn_cast<StructType>(Ty)) {
|
||||
} else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
|
||||
Out << "{ ";
|
||||
for (StructType::ElementTypes::const_iterator
|
||||
I = STy->getElementTypes().begin(),
|
||||
|
@ -476,12 +472,12 @@ ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
|
|||
printType(*I);
|
||||
}
|
||||
Out << " }";
|
||||
} else if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
|
||||
} else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
|
||||
printType(PTy->getElementType()) << "*";
|
||||
} else if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
|
||||
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
|
||||
Out << "[" << ATy->getNumElements() << " x ";
|
||||
printType(ATy->getElementType()) << "]";
|
||||
} else if (OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
|
||||
} else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
|
||||
Out << OTy->getDescription();
|
||||
} else {
|
||||
assert(Ty->isPrimitiveType() && "Unknown derived type!");
|
||||
|
@ -503,13 +499,14 @@ void AssemblyWriter::printModule(const Module *M) {
|
|||
if (M->hasSymbolTable())
|
||||
printSymbolTable(*M->getSymbolTable());
|
||||
|
||||
for_each(M->gbegin(), M->gend(),
|
||||
bind_obj(this, &AssemblyWriter::printGlobal));
|
||||
for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
|
||||
printGlobal(I);
|
||||
|
||||
Out << "\nimplementation ; Functions:\n";
|
||||
|
||||
// Output all of the functions...
|
||||
for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::printFunction));
|
||||
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
printFunction(I);
|
||||
}
|
||||
|
||||
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||
|
@ -524,7 +521,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
|||
if (GV->hasInitializer())
|
||||
writeOperand(GV->getInitializer(), false, false);
|
||||
|
||||
printInfoComment(GV);
|
||||
printInfoComment(*GV);
|
||||
Out << "\n";
|
||||
}
|
||||
|
||||
|
@ -566,50 +563,49 @@ void AssemblyWriter::printConstant(const Constant *CPV) {
|
|||
// Write the value out now...
|
||||
writeOperand(CPV, true, false);
|
||||
|
||||
printInfoComment(CPV);
|
||||
printInfoComment(*CPV);
|
||||
Out << "\n";
|
||||
}
|
||||
|
||||
// printFunction - Print all aspects of a function.
|
||||
//
|
||||
void AssemblyWriter::printFunction(const Function *M) {
|
||||
void AssemblyWriter::printFunction(const Function *F) {
|
||||
// Print out the return type and name...
|
||||
Out << "\n" << (M->isExternal() ? "declare " : "")
|
||||
<< (M->hasInternalLinkage() ? "internal " : "");
|
||||
printType(M->getReturnType()) << " %" << M->getName() << "(";
|
||||
Table.incorporateFunction(M);
|
||||
Out << "\n" << (F->isExternal() ? "declare " : "")
|
||||
<< (F->hasInternalLinkage() ? "internal " : "");
|
||||
printType(F->getReturnType()) << " %" << F->getName() << "(";
|
||||
Table.incorporateFunction(F);
|
||||
|
||||
// Loop over the arguments, printing them...
|
||||
const FunctionType *MT = M->getFunctionType();
|
||||
const FunctionType *FT = F->getFunctionType();
|
||||
|
||||
if (!M->isExternal()) {
|
||||
for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
|
||||
bind_obj(this, &AssemblyWriter::printArgument));
|
||||
if (!F->isExternal()) {
|
||||
for(Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
|
||||
printArgument(I);
|
||||
} else {
|
||||
// Loop over the arguments, printing them...
|
||||
const FunctionType *MT = M->getFunctionType();
|
||||
for (FunctionType::ParamTypes::const_iterator I = MT->getParamTypes().begin(),
|
||||
E = MT->getParamTypes().end(); I != E; ++I) {
|
||||
if (I != MT->getParamTypes().begin()) Out << ", ";
|
||||
for (FunctionType::ParamTypes::const_iterator I = FT->getParamTypes().begin(),
|
||||
E = FT->getParamTypes().end(); I != E; ++I) {
|
||||
if (I != FT->getParamTypes().begin()) Out << ", ";
|
||||
printType(*I);
|
||||
}
|
||||
}
|
||||
|
||||
// Finish printing arguments...
|
||||
if (MT->isVarArg()) {
|
||||
if (MT->getParamTypes().size()) Out << ", ";
|
||||
if (FT->isVarArg()) {
|
||||
if (FT->getParamTypes().size()) Out << ", ";
|
||||
Out << "..."; // Output varargs portion of signature!
|
||||
}
|
||||
Out << ")";
|
||||
|
||||
if (M->isExternal()) {
|
||||
if (F->isExternal()) {
|
||||
Out << "\n";
|
||||
} else {
|
||||
Out << " {";
|
||||
|
||||
// Output all of its basic blocks... for the function
|
||||
for_each(M->begin(), M->end(),
|
||||
bind_obj(this, &AssemblyWriter::printBasicBlock));
|
||||
for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
|
||||
printBasicBlock(I);
|
||||
|
||||
Out << "}\n";
|
||||
}
|
||||
|
@ -622,7 +618,7 @@ void AssemblyWriter::printFunction(const Function *M) {
|
|||
//
|
||||
void AssemblyWriter::printArgument(const Argument *Arg) {
|
||||
// Insert commas as we go... the first arg doesn't get a comma
|
||||
if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
|
||||
if (Arg != &Arg->getParent()->afront()) Out << ", ";
|
||||
|
||||
// Output type...
|
||||
printType(Arg->getType());
|
||||
|
@ -653,72 +649,72 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
|
|||
Out << "\n";
|
||||
|
||||
// Output all of the instructions in the basic block...
|
||||
for_each(BB->begin(), BB->end(),
|
||||
bind_obj(this, &AssemblyWriter::printInstruction));
|
||||
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
||||
printInstruction(*I);
|
||||
}
|
||||
|
||||
|
||||
// printInfoComment - Print a little comment after the instruction indicating
|
||||
// which slot it occupies.
|
||||
//
|
||||
void AssemblyWriter::printInfoComment(const Value *V) {
|
||||
if (V->getType() != Type::VoidTy) {
|
||||
void AssemblyWriter::printInfoComment(const Value &V) {
|
||||
if (V.getType() != Type::VoidTy) {
|
||||
Out << "\t\t; <";
|
||||
printType(V->getType()) << ">";
|
||||
printType(V.getType()) << ">";
|
||||
|
||||
if (!V->hasName()) {
|
||||
int Slot = Table.getValSlot(V); // Print out the def slot taken...
|
||||
if (!V.hasName()) {
|
||||
int Slot = Table.getValSlot(&V); // Print out the def slot taken...
|
||||
if (Slot >= 0) Out << ":" << Slot;
|
||||
else Out << ":<badref>";
|
||||
}
|
||||
Out << " [#uses=" << V->use_size() << "]"; // Output # uses
|
||||
Out << " [#uses=" << V.use_size() << "]"; // Output # uses
|
||||
}
|
||||
}
|
||||
|
||||
// printInstruction - This member is called for each Instruction in a methd.
|
||||
//
|
||||
void AssemblyWriter::printInstruction(const Instruction *I) {
|
||||
void AssemblyWriter::printInstruction(const Instruction &I) {
|
||||
Out << "\t";
|
||||
|
||||
// Print out name if it exists...
|
||||
if (I && I->hasName())
|
||||
Out << "%" << I->getName() << " = ";
|
||||
if (I.hasName())
|
||||
Out << "%" << I.getName() << " = ";
|
||||
|
||||
// Print out the opcode...
|
||||
Out << I->getOpcodeName();
|
||||
Out << I.getOpcodeName();
|
||||
|
||||
// Print out the type of the operands...
|
||||
const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
|
||||
const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0;
|
||||
|
||||
// Special case conditional branches to swizzle the condition out to the front
|
||||
if (isa<BranchInst>(I) && I->getNumOperands() > 1) {
|
||||
writeOperand(I->getOperand(2), true);
|
||||
if (isa<BranchInst>(I) && I.getNumOperands() > 1) {
|
||||
writeOperand(I.getOperand(2), true);
|
||||
Out << ",";
|
||||
writeOperand(Operand, true);
|
||||
Out << ",";
|
||||
writeOperand(I->getOperand(1), true);
|
||||
writeOperand(I.getOperand(1), true);
|
||||
|
||||
} else if (isa<SwitchInst>(I)) {
|
||||
// Special case switch statement to get formatting nice and correct...
|
||||
writeOperand(Operand , true); Out << ",";
|
||||
writeOperand(I->getOperand(1), true); Out << " [";
|
||||
writeOperand(Operand , true); Out << ",";
|
||||
writeOperand(I.getOperand(1), true); Out << " [";
|
||||
|
||||
for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
|
||||
for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
|
||||
Out << "\n\t\t";
|
||||
writeOperand(I->getOperand(op ), true); Out << ",";
|
||||
writeOperand(I->getOperand(op+1), true);
|
||||
writeOperand(I.getOperand(op ), true); Out << ",";
|
||||
writeOperand(I.getOperand(op+1), true);
|
||||
}
|
||||
Out << "\n\t]";
|
||||
} else if (isa<PHINode>(I)) {
|
||||
Out << " ";
|
||||
printType(I->getType());
|
||||
printType(I.getType());
|
||||
Out << " ";
|
||||
|
||||
for (unsigned op = 0, Eop = I->getNumOperands(); op < Eop; op += 2) {
|
||||
for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
|
||||
if (op) Out << ", ";
|
||||
Out << "[";
|
||||
writeOperand(I->getOperand(op ), false); Out << ",";
|
||||
writeOperand(I->getOperand(op+1), false); Out << " ]";
|
||||
writeOperand(I.getOperand(op ), false); Out << ",";
|
||||
writeOperand(I.getOperand(op+1), false); Out << " ]";
|
||||
}
|
||||
} else if (isa<ReturnInst>(I) && !Operand) {
|
||||
Out << " void";
|
||||
|
@ -740,21 +736,21 @@ void AssemblyWriter::printInstruction(const Instruction *I) {
|
|||
writeOperand(Operand, true);
|
||||
}
|
||||
Out << "(";
|
||||
if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
|
||||
for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
|
||||
if (I.getNumOperands() > 1) writeOperand(I.getOperand(1), true);
|
||||
for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; ++op) {
|
||||
Out << ",";
|
||||
writeOperand(I->getOperand(op), true);
|
||||
writeOperand(I.getOperand(op), true);
|
||||
}
|
||||
|
||||
Out << " )";
|
||||
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) {
|
||||
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
|
||||
// TODO: Should try to print out short form of the Invoke instruction
|
||||
writeOperand(Operand, true);
|
||||
Out << "(";
|
||||
if (I->getNumOperands() > 3) writeOperand(I->getOperand(3), true);
|
||||
for (unsigned op = 4, Eop = I->getNumOperands(); op < Eop; ++op) {
|
||||
if (I.getNumOperands() > 3) writeOperand(I.getOperand(3), true);
|
||||
for (unsigned op = 4, Eop = I.getNumOperands(); op < Eop; ++op) {
|
||||
Out << ",";
|
||||
writeOperand(I->getOperand(op), true);
|
||||
writeOperand(I.getOperand(op), true);
|
||||
}
|
||||
|
||||
Out << " )\n\t\t\tto";
|
||||
|
@ -762,7 +758,7 @@ void AssemblyWriter::printInstruction(const Instruction *I) {
|
|||
Out << " except";
|
||||
writeOperand(II->getExceptionalDest(), true);
|
||||
|
||||
} else if (const AllocationInst *AI = dyn_cast<AllocationInst>(I)) {
|
||||
} else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
|
||||
Out << " ";
|
||||
printType(AI->getType()->getElementType());
|
||||
if (AI->isArrayAllocation()) {
|
||||
|
@ -772,7 +768,7 @@ void AssemblyWriter::printInstruction(const Instruction *I) {
|
|||
} else if (isa<CastInst>(I)) {
|
||||
if (Operand) writeOperand(Operand, true);
|
||||
Out << " to ";
|
||||
printType(I->getType());
|
||||
printType(I.getType());
|
||||
} else if (Operand) { // Print the normal way...
|
||||
|
||||
// PrintAllTypes - Instructions who have operands of all the same type
|
||||
|
@ -781,8 +777,8 @@ void AssemblyWriter::printInstruction(const Instruction *I) {
|
|||
bool PrintAllTypes = false;
|
||||
const Type *TheType = Operand->getType();
|
||||
|
||||
for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
|
||||
Operand = I->getOperand(i);
|
||||
for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
|
||||
Operand = I.getOperand(i);
|
||||
if (Operand->getType() != TheType) {
|
||||
PrintAllTypes = true; // We have differing types! Print them all!
|
||||
break;
|
||||
|
@ -794,12 +790,12 @@ void AssemblyWriter::printInstruction(const Instruction *I) {
|
|||
|
||||
if (!PrintAllTypes) {
|
||||
Out << " ";
|
||||
printType(I->getOperand(0)->getType());
|
||||
printType(I.getOperand(0)->getType());
|
||||
}
|
||||
|
||||
for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
|
||||
for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
|
||||
if (i) Out << ",";
|
||||
writeOperand(I->getOperand(i), PrintAllTypes);
|
||||
writeOperand(I.getOperand(i), PrintAllTypes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,29 +4,61 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ValueHolderImpl.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/iTerminators.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Constant.h"
|
||||
#include "llvm/iPHINode.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "SymbolTableListTraitsImpl.h"
|
||||
#include <algorithm>
|
||||
|
||||
// Instantiate Templates - This ugliness is the price we have to pay
|
||||
// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
|
||||
// DummyInst - An instance of this class is used to mark the end of the
|
||||
// instruction list. This is not a real instruction.
|
||||
//
|
||||
template class ValueHolder<Instruction, BasicBlock, Function>;
|
||||
struct DummyInst : public Instruction {
|
||||
DummyInst() : Instruction(Type::VoidTy, NumOtherOps) {}
|
||||
|
||||
virtual Instruction *clone() const { assert(0 && "Cannot clone EOL");abort();}
|
||||
virtual const char *getOpcodeName() const { return "*end-of-list-inst*"; }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast...
|
||||
static inline bool classof(const DummyInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == NumOtherOps;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
}
|
||||
};
|
||||
|
||||
Instruction *ilist_traits<Instruction>::createNode() {
|
||||
return new DummyInst();
|
||||
}
|
||||
iplist<Instruction> &ilist_traits<Instruction>::getList(BasicBlock *BB) {
|
||||
return BB->getInstList();
|
||||
}
|
||||
|
||||
// Explicit instantiation of SymbolTableListTraits since some of the methods
|
||||
// are not in the public header file...
|
||||
template SymbolTableListTraits<Instruction, BasicBlock, Function>;
|
||||
|
||||
|
||||
BasicBlock::BasicBlock(const std::string &name, Function *Parent)
|
||||
: Value(Type::LabelTy, Value::BasicBlockVal, name), InstList(this, 0),
|
||||
: Value(Type::LabelTy, Value::BasicBlockVal, name),
|
||||
machineInstrVec(new MachineCodeForBasicBlock) {
|
||||
// Initialize the instlist...
|
||||
InstList.setItemParent(this);
|
||||
|
||||
if (Parent)
|
||||
Parent->getBasicBlocks().push_back(this);
|
||||
Parent->getBasicBlockList().push_back(this);
|
||||
}
|
||||
|
||||
BasicBlock::~BasicBlock() {
|
||||
dropAllReferences();
|
||||
InstList.delete_all();
|
||||
InstList.clear();
|
||||
delete machineInstrVec;
|
||||
}
|
||||
|
||||
|
@ -40,33 +72,19 @@ void BasicBlock::setName(const std::string &name, SymbolTable *ST) {
|
|||
if (P && hasName()) P->getSymbolTable()->insert(this);
|
||||
}
|
||||
|
||||
void BasicBlock::setParent(Function *parent) {
|
||||
if (getParent() && hasName())
|
||||
getParent()->getSymbolTable()->remove(this);
|
||||
|
||||
InstList.setParent(parent);
|
||||
|
||||
if (getParent() && hasName())
|
||||
getParent()->getSymbolTableSure()->insert(this);
|
||||
}
|
||||
|
||||
TerminatorInst *BasicBlock::getTerminator() {
|
||||
if (InstList.empty()) return 0;
|
||||
Instruction *T = InstList.back();
|
||||
if (isa<TerminatorInst>(T)) return cast<TerminatorInst>(T);
|
||||
return 0;
|
||||
return dyn_cast<TerminatorInst>(&InstList.back());
|
||||
}
|
||||
|
||||
const TerminatorInst *const BasicBlock::getTerminator() const {
|
||||
if (InstList.empty()) return 0;
|
||||
if (const TerminatorInst *TI = dyn_cast<TerminatorInst>(InstList.back()))
|
||||
return TI;
|
||||
return 0;
|
||||
return dyn_cast<TerminatorInst>(&InstList.back());
|
||||
}
|
||||
|
||||
void BasicBlock::dropAllReferences() {
|
||||
for_each(InstList.begin(), InstList.end(),
|
||||
std::mem_fun(&Instruction::dropAllReferences));
|
||||
for(iterator I = begin(), E = end(); I != E; ++I)
|
||||
I->dropAllReferences();
|
||||
}
|
||||
|
||||
// hasConstantReferences() - This predicate is true if there is a
|
||||
|
@ -123,7 +141,7 @@ void BasicBlock::removePredecessor(BasicBlock *Pred) {
|
|||
|
||||
if (max_idx <= 2) { // <= Two predecessors BEFORE I remove one?
|
||||
// Yup, loop through and nuke the PHI nodes
|
||||
while (PHINode *PN = dyn_cast<PHINode>(front())) {
|
||||
while (PHINode *PN = dyn_cast<PHINode>(&front())) {
|
||||
PN->removeIncomingValue(Pred); // Remove the predecessor first...
|
||||
|
||||
assert(PN->getNumIncomingValues() == max_idx-1 &&
|
||||
|
@ -134,12 +152,12 @@ void BasicBlock::removePredecessor(BasicBlock *Pred) {
|
|||
PN->replaceAllUsesWith(PN->getOperand(0));
|
||||
else // Otherwise there are no incoming values/edges, replace with dummy
|
||||
PN->replaceAllUsesWith(Constant::getNullValue(PN->getType()));
|
||||
delete getInstList().remove(begin()); // Remove the PHI node
|
||||
getInstList().pop_front(); // Remove the PHI node
|
||||
}
|
||||
} else {
|
||||
// Okay, now we know that we need to remove predecessor #pred_idx from all
|
||||
// PHI nodes. Iterate over each PHI node fixing them up
|
||||
for (iterator II = begin(); PHINode *PN = dyn_cast<PHINode>(*II); ++II)
|
||||
for (iterator II = begin(); PHINode *PN = dyn_cast<PHINode>(&*II); ++II)
|
||||
PN->removeIncomingValue(Pred);
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +188,7 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I) {
|
|||
iterator EndIt = end();
|
||||
Inst = InstList.remove(--EndIt); // Remove from end
|
||||
New->InstList.push_front(Inst); // Add to front
|
||||
} while (Inst != *I); // Loop until we move the specified instruction.
|
||||
} while (Inst != &*I); // Loop until we move the specified instruction.
|
||||
|
||||
// Add a branch instruction to the newly formed basic block.
|
||||
InstList.push_back(new BranchInst(New));
|
||||
|
@ -186,7 +204,7 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I) {
|
|||
// incoming values...
|
||||
BasicBlock *Successor = *I;
|
||||
for (BasicBlock::iterator II = Successor->begin();
|
||||
PHINode *PN = dyn_cast<PHINode>(*II); ++II) {
|
||||
PHINode *PN = dyn_cast<PHINode>(&*II); ++II) {
|
||||
int IDX = PN->getBasicBlockIndex(this);
|
||||
while (IDX != -1) {
|
||||
PN->setIncomingBlock((unsigned)IDX, New);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/GlobalValue.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/SlotCalculator.h"
|
||||
#include "Support/StringExtras.h"
|
||||
|
|
|
@ -21,7 +21,7 @@ using std::set;
|
|||
AnalysisID DominatorSet::ID(AnalysisID::create<DominatorSet>(), true);
|
||||
AnalysisID DominatorSet::PostDomID(AnalysisID::create<DominatorSet>(), true);
|
||||
|
||||
bool DominatorSet::runOnFunction(Function *F) {
|
||||
bool DominatorSet::runOnFunction(Function &F) {
|
||||
Doms.clear(); // Reset from the last time we were run...
|
||||
|
||||
if (isPostDominator())
|
||||
|
@ -40,17 +40,17 @@ bool DominatorSet::dominates(Instruction *A, Instruction *B) const {
|
|||
|
||||
// Loop through the basic block until we find A or B.
|
||||
BasicBlock::iterator I = BBA->begin();
|
||||
for (; *I != A && *I != B; ++I) /*empty*/;
|
||||
for (; &*I != A && &*I != B; ++I) /*empty*/;
|
||||
|
||||
// A dominates B if it is found first in the basic block...
|
||||
return *I == A;
|
||||
return &*I == A;
|
||||
}
|
||||
|
||||
// calcForwardDominatorSet - This method calculates the forward dominator sets
|
||||
// for the specified function.
|
||||
//
|
||||
void DominatorSet::calcForwardDominatorSet(Function *M) {
|
||||
Root = M->getEntryNode();
|
||||
void DominatorSet::calcForwardDominatorSet(Function &F) {
|
||||
Root = &F.getEntryNode();
|
||||
assert(pred_begin(Root) == pred_end(Root) &&
|
||||
"Root node has predecessors in function!");
|
||||
|
||||
|
@ -59,7 +59,7 @@ void DominatorSet::calcForwardDominatorSet(Function *M) {
|
|||
Changed = false;
|
||||
|
||||
DomSetType WorkingSet;
|
||||
df_iterator<Function*> It = df_begin(M), End = df_end(M);
|
||||
df_iterator<Function*> It = df_begin(&F), End = df_end(&F);
|
||||
for ( ; It != End; ++It) {
|
||||
BasicBlock *BB = *It;
|
||||
pred_iterator PI = pred_begin(BB), PEnd = pred_end(BB);
|
||||
|
@ -93,7 +93,7 @@ void DominatorSet::calcForwardDominatorSet(Function *M) {
|
|||
// only have a single exit node (return stmt), then calculates the post
|
||||
// dominance sets for the function.
|
||||
//
|
||||
void DominatorSet::calcPostDominatorSet(Function *F) {
|
||||
void DominatorSet::calcPostDominatorSet(Function &F) {
|
||||
// Since we require that the unify all exit nodes pass has been run, we know
|
||||
// that there can be at most one return instruction in the function left.
|
||||
// Get it.
|
||||
|
@ -101,8 +101,8 @@ void DominatorSet::calcPostDominatorSet(Function *F) {
|
|||
Root = getAnalysis<UnifyFunctionExitNodes>().getExitNode();
|
||||
|
||||
if (Root == 0) { // No exit node for the function? Postdomsets are all empty
|
||||
for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
|
||||
Doms[*FI] = DomSetType();
|
||||
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
|
||||
Doms[FI] = DomSetType();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,24 @@
|
|||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/iOther.h"
|
||||
#include "llvm/Argument.h"
|
||||
#include "ValueHolderImpl.h"
|
||||
#include "SymbolTableListTraitsImpl.h"
|
||||
|
||||
iplist<BasicBlock> &ilist_traits<BasicBlock>::getList(Function *F) {
|
||||
return F->getBasicBlockList();
|
||||
}
|
||||
|
||||
Argument *ilist_traits<Argument>::createNode() {
|
||||
return new Argument(Type::IntTy);
|
||||
}
|
||||
|
||||
iplist<Argument> &ilist_traits<Argument>::getList(Function *F) {
|
||||
return F->getArgumentList();
|
||||
}
|
||||
|
||||
// Explicit instantiations of SymbolTableListTraits since some of the methods
|
||||
// are not in the public header file...
|
||||
template SymbolTableListTraits<Argument, Function, Function>;
|
||||
template SymbolTableListTraits<BasicBlock, Function, Function>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Argument Implementation
|
||||
|
@ -28,36 +45,28 @@ void Argument::setName(const std::string &name, SymbolTable *ST) {
|
|||
if (P && hasName()) P->getSymbolTable()->insert(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Function Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// Instantiate Templates - This ugliness is the price we have to pay
|
||||
// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
|
||||
//
|
||||
template class ValueHolder<Argument , Function, Function>;
|
||||
template class ValueHolder<BasicBlock, Function, Function>;
|
||||
|
||||
Function::Function(const FunctionType *Ty, bool isInternal,
|
||||
const std::string &name)
|
||||
: GlobalValue(PointerType::get(Ty), Value::FunctionVal, isInternal, name),
|
||||
BasicBlocks(this), ArgumentList(this, this) {
|
||||
: GlobalValue(PointerType::get(Ty), Value::FunctionVal, isInternal, name) {
|
||||
BasicBlocks.setItemParent(this);
|
||||
BasicBlocks.setParent(this);
|
||||
ArgumentList.setItemParent(this);
|
||||
ArgumentList.setParent(this);
|
||||
ParentSymTab = SymTab = 0;
|
||||
}
|
||||
|
||||
Function::~Function() {
|
||||
dropAllReferences(); // After this it is safe to delete instructions.
|
||||
|
||||
// TODO: Should remove from the end, not the beginning of vector!
|
||||
iterator BI = begin();
|
||||
while ((BI = begin()) != end())
|
||||
delete BasicBlocks.remove(BI);
|
||||
BasicBlocks.clear(); // Delete all basic blocks...
|
||||
|
||||
// Delete all of the method arguments and unlink from symbol table...
|
||||
ArgumentList.delete_all();
|
||||
ArgumentList.clear();
|
||||
ArgumentList.setParent(0);
|
||||
delete SymTab;
|
||||
}
|
||||
|
@ -118,7 +127,8 @@ bool Function::hasSymbolTable() const {
|
|||
// delete.
|
||||
//
|
||||
void Function::dropAllReferences() {
|
||||
for_each(begin(), end(), std::mem_fun(&BasicBlock::dropAllReferences));
|
||||
for (iterator I = begin(), E = end(); I != E; ++I)
|
||||
I->dropAllReferences();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "llvm/iOther.h"
|
||||
#include "llvm/iPHINode.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/Type.h"
|
||||
|
|
|
@ -4,10 +4,9 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/Type.h"
|
||||
|
||||
Instruction::Instruction(const Type *ty, unsigned it, const std::string &Name)
|
||||
: User(ty, Value::InstructionVal, Name) {
|
||||
|
|
|
@ -11,14 +11,29 @@
|
|||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "Support/STLExtras.h"
|
||||
#include "ValueHolderImpl.h"
|
||||
#include "SymbolTableListTraitsImpl.h"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
// Instantiate Templates - This ugliness is the price we have to pay
|
||||
// for having a DefHolderImpl.h file seperate from DefHolder.h! :(
|
||||
//
|
||||
template class ValueHolder<GlobalVariable, Module, Module>;
|
||||
template class ValueHolder<Function, Module, Module>;
|
||||
Function *ilist_traits<Function>::createNode() {
|
||||
return new Function(FunctionType::get(Type::VoidTy,std::vector<const Type*>(),
|
||||
false), false);
|
||||
}
|
||||
GlobalVariable *ilist_traits<GlobalVariable>::createNode() {
|
||||
return new GlobalVariable(Type::IntTy, false, false);
|
||||
}
|
||||
|
||||
iplist<Function> &ilist_traits<Function>::getList(Module *M) {
|
||||
return M->getFunctionList();
|
||||
}
|
||||
iplist<GlobalVariable> &ilist_traits<GlobalVariable>::getList(Module *M) {
|
||||
return M->getGlobalList();
|
||||
}
|
||||
|
||||
// Explicit instantiations of SymbolTableListTraits since some of the methods
|
||||
// are not in the public header file...
|
||||
template SymbolTableListTraits<GlobalVariable, Module, Module>;
|
||||
template SymbolTableListTraits<Function, Module, Module>;
|
||||
|
||||
// Define the GlobalValueRefMap as a struct that wraps a map so that we don't
|
||||
// have Module.h depend on <map>
|
||||
|
@ -27,16 +42,20 @@ struct GlobalValueRefMap : public std::map<GlobalValue*, ConstantPointerRef*>{
|
|||
};
|
||||
|
||||
|
||||
Module::Module() : GlobalList(this, this), FunctionList(this, this) {
|
||||
Module::Module() {
|
||||
FunctionList.setItemParent(this);
|
||||
FunctionList.setParent(this);
|
||||
GlobalList.setItemParent(this);
|
||||
GlobalList.setParent(this);
|
||||
GVRefMap = 0;
|
||||
SymTab = 0;
|
||||
}
|
||||
|
||||
Module::~Module() {
|
||||
dropAllReferences();
|
||||
GlobalList.delete_all();
|
||||
GlobalList.clear();
|
||||
GlobalList.setParent(0);
|
||||
FunctionList.delete_all();
|
||||
FunctionList.clear();
|
||||
FunctionList.setParent(0);
|
||||
delete SymTab;
|
||||
}
|
||||
|
@ -136,11 +155,11 @@ std::string Module::getTypeName(const Type *Ty) {
|
|||
// delete.
|
||||
//
|
||||
void Module::dropAllReferences() {
|
||||
for_each(FunctionList.begin(), FunctionList.end(),
|
||||
std::mem_fun(&Function::dropAllReferences));
|
||||
for(Module::iterator I = begin(), E = end(); I != E; ++I)
|
||||
I->dropAllReferences();
|
||||
|
||||
for_each(GlobalList.begin(), GlobalList.end(),
|
||||
std::mem_fun(&GlobalVariable::dropAllReferences));
|
||||
for(Module::giterator I = gbegin(), E = gend(); I != E; ++I)
|
||||
I->dropAllReferences();
|
||||
|
||||
// If there are any GlobalVariable references still out there, nuke them now.
|
||||
// Since all references are hereby dropped, nothing could possibly reference
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include "llvm/PassManager.h"
|
||||
#include "PassManagerT.h" // PassManagerT implementation
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "Support/STLExtras.h"
|
||||
#include "Support/CommandLine.h"
|
||||
#include <typeinfo>
|
||||
|
@ -75,7 +73,7 @@ void AnalysisUsage::preservesCFG() {
|
|||
PassManager::PassManager() : PM(new PassManagerT<Module>()) {}
|
||||
PassManager::~PassManager() { delete PM; }
|
||||
void PassManager::add(Pass *P) { PM->add(P); }
|
||||
bool PassManager::run(Module *M) { return PM->run(M); }
|
||||
bool PassManager::run(Module &M) { return PM->run(M); }
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -220,11 +218,11 @@ const char *Pass::getPassName() const { return typeid(*this).name(); }
|
|||
// run - On a module, we run this pass by initializing, runOnFunction'ing once
|
||||
// for every function in the module, then by finalizing.
|
||||
//
|
||||
bool FunctionPass::run(Module *M) {
|
||||
bool FunctionPass::run(Module &M) {
|
||||
bool Changed = doInitialization(M);
|
||||
|
||||
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
if (!(*I)->isExternal()) // Passes are not run on external functions!
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
||||
if (!I->isExternal()) // Passes are not run on external functions!
|
||||
Changed |= runOnFunction(*I);
|
||||
|
||||
return Changed | doFinalization(M);
|
||||
|
@ -232,11 +230,11 @@ bool FunctionPass::run(Module *M) {
|
|||
|
||||
// run - On a function, we simply initialize, run the function, then finalize.
|
||||
//
|
||||
bool FunctionPass::run(Function *F) {
|
||||
if (F->isExternal()) return false;// Passes are not run on external functions!
|
||||
bool FunctionPass::run(Function &F) {
|
||||
if (F.isExternal()) return false;// Passes are not run on external functions!
|
||||
|
||||
return doInitialization(F->getParent()) | runOnFunction(F)
|
||||
| doFinalization(F->getParent());
|
||||
return doInitialization(*F.getParent()) | runOnFunction(F)
|
||||
| doFinalization(*F.getParent());
|
||||
}
|
||||
|
||||
void FunctionPass::addToPassManager(PassManagerT<Module> *PM,
|
||||
|
@ -256,9 +254,9 @@ void FunctionPass::addToPassManager(PassManagerT<Function> *PM,
|
|||
// To run this pass on a function, we simply call runOnBasicBlock once for each
|
||||
// function.
|
||||
//
|
||||
bool BasicBlockPass::runOnFunction(Function *F) {
|
||||
bool BasicBlockPass::runOnFunction(Function &F) {
|
||||
bool Changed = false;
|
||||
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
|
||||
Changed |= runOnBasicBlock(*I);
|
||||
return Changed;
|
||||
}
|
||||
|
@ -266,8 +264,8 @@ bool BasicBlockPass::runOnFunction(Function *F) {
|
|||
// To run directly on the basic block, we initialize, runOnBasicBlock, then
|
||||
// finalize.
|
||||
//
|
||||
bool BasicBlockPass::run(BasicBlock *BB) {
|
||||
Module *M = BB->getParent()->getParent();
|
||||
bool BasicBlockPass::run(BasicBlock &BB) {
|
||||
Module &M = *BB.getParent()->getParent();
|
||||
return doInitialization(M) | runOnBasicBlock(BB) | doFinalization(M);
|
||||
}
|
||||
|
||||
|
|
|
@ -424,7 +424,7 @@ template<> struct PassManagerTraits<BasicBlock> : public BasicBlockPass {
|
|||
// runPass - Specify how the pass should be run on the UnitType
|
||||
static bool runPass(PassClass *P, BasicBlock *M) {
|
||||
// todo, init and finalize
|
||||
return P->runOnBasicBlock(M);
|
||||
return P->runOnBasicBlock(*M);
|
||||
}
|
||||
|
||||
// Dummy implementation of PassStarted/PassEnded
|
||||
|
@ -437,9 +437,9 @@ template<> struct PassManagerTraits<BasicBlock> : public BasicBlockPass {
|
|||
virtual const char *getPassName() const { return "BasicBlock Pass Manager"; }
|
||||
|
||||
// Implement the BasicBlockPass interface...
|
||||
virtual bool doInitialization(Module *M);
|
||||
virtual bool runOnBasicBlock(BasicBlock *BB);
|
||||
virtual bool doFinalization(Module *M);
|
||||
virtual bool doInitialization(Module &M);
|
||||
virtual bool runOnBasicBlock(BasicBlock &BB);
|
||||
virtual bool doFinalization(Module &M);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
|
@ -472,7 +472,7 @@ template<> struct PassManagerTraits<Function> : public FunctionPass {
|
|||
|
||||
// runPass - Specify how the pass should be run on the UnitType
|
||||
static bool runPass(PassClass *P, Function *F) {
|
||||
return P->runOnFunction(F);
|
||||
return P->runOnFunction(*F);
|
||||
}
|
||||
|
||||
// Dummy implementation of PassStarted/PassEnded
|
||||
|
@ -485,9 +485,9 @@ template<> struct PassManagerTraits<Function> : public FunctionPass {
|
|||
virtual const char *getPassName() const { return "Function Pass Manager"; }
|
||||
|
||||
// Implement the FunctionPass interface...
|
||||
virtual bool doInitialization(Module *M);
|
||||
virtual bool runOnFunction(Function *F);
|
||||
virtual bool doFinalization(Module *M);
|
||||
virtual bool doInitialization(Module &M);
|
||||
virtual bool runOnFunction(Function &F);
|
||||
virtual bool doFinalization(Module &M);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
|
@ -515,7 +515,7 @@ template<> struct PassManagerTraits<Module> : public Pass {
|
|||
typedef AnalysisResolver ParentClass;
|
||||
|
||||
// runPass - Specify how the pass should be run on the UnitType
|
||||
static bool runPass(PassClass *P, Module *M) { return P->run(M); }
|
||||
static bool runPass(PassClass *P, Module *M) { return P->run(*M); }
|
||||
|
||||
// getPMName() - Return the name of the unit the PassManager operates on for
|
||||
// debugging.
|
||||
|
@ -539,9 +539,9 @@ template<> struct PassManagerTraits<Module> : public Pass {
|
|||
}
|
||||
|
||||
// run - Implement the PassManager interface...
|
||||
bool run(Module *M) {
|
||||
bool run(Module &M) {
|
||||
TimeInfo = TimingInfo::create();
|
||||
bool Result = ((PassManagerT<Module>*)this)->runOnUnit(M);
|
||||
bool Result = ((PassManagerT<Module>*)this)->runOnUnit(&M);
|
||||
if (TimeInfo) {
|
||||
delete TimeInfo;
|
||||
TimeInfo = 0;
|
||||
|
@ -563,18 +563,18 @@ template<> struct PassManagerTraits<Module> : public Pass {
|
|||
|
||||
// PassManagerTraits<BasicBlock> Implementations
|
||||
//
|
||||
inline bool PassManagerTraits<BasicBlock>::doInitialization(Module *M) {
|
||||
inline bool PassManagerTraits<BasicBlock>::doInitialization(Module &M) {
|
||||
bool Changed = false;
|
||||
for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
|
||||
((PMType*)this)->Passes[i]->doInitialization(M);
|
||||
return Changed;
|
||||
}
|
||||
|
||||
inline bool PassManagerTraits<BasicBlock>::runOnBasicBlock(BasicBlock *BB) {
|
||||
return ((PMType*)this)->runOnUnit(BB);
|
||||
inline bool PassManagerTraits<BasicBlock>::runOnBasicBlock(BasicBlock &BB) {
|
||||
return ((PMType*)this)->runOnUnit(&BB);
|
||||
}
|
||||
|
||||
inline bool PassManagerTraits<BasicBlock>::doFinalization(Module *M) {
|
||||
inline bool PassManagerTraits<BasicBlock>::doFinalization(Module &M) {
|
||||
bool Changed = false;
|
||||
for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
|
||||
((PMType*)this)->Passes[i]->doFinalization(M);
|
||||
|
@ -584,18 +584,18 @@ inline bool PassManagerTraits<BasicBlock>::doFinalization(Module *M) {
|
|||
|
||||
// PassManagerTraits<Function> Implementations
|
||||
//
|
||||
inline bool PassManagerTraits<Function>::doInitialization(Module *M) {
|
||||
inline bool PassManagerTraits<Function>::doInitialization(Module &M) {
|
||||
bool Changed = false;
|
||||
for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
|
||||
((PMType*)this)->Passes[i]->doInitialization(M);
|
||||
return Changed;
|
||||
}
|
||||
|
||||
inline bool PassManagerTraits<Function>::runOnFunction(Function *F) {
|
||||
return ((PMType*)this)->runOnUnit(F);
|
||||
inline bool PassManagerTraits<Function>::runOnFunction(Function &F) {
|
||||
return ((PMType*)this)->runOnUnit(&F);
|
||||
}
|
||||
|
||||
inline bool PassManagerTraits<Function>::doFinalization(Module *M) {
|
||||
inline bool PassManagerTraits<Function>::doFinalization(Module &M) {
|
||||
bool Changed = false;
|
||||
for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i)
|
||||
((PMType*)this)->Passes[i]->doFinalization(M);
|
||||
|
|
|
@ -11,15 +11,11 @@
|
|||
|
||||
#include "llvm/SlotCalculator.h"
|
||||
#include "llvm/Analysis/ConstantsScanner.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/iOther.h"
|
||||
#include "llvm/Constant.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/Argument.h"
|
||||
#include "Support/DepthFirstIterator.h"
|
||||
#include "Support/STLExtras.h"
|
||||
#include <algorithm>
|
||||
|
@ -75,20 +71,22 @@ void SlotCalculator::processModule() {
|
|||
//
|
||||
for (Module::const_giterator I = TheModule->gbegin(), E = TheModule->gend();
|
||||
I != E; ++I) {
|
||||
if ((*I)->hasInitializer())
|
||||
insertValue((*I)->getInitializer());
|
||||
if (I->hasInitializer())
|
||||
insertValue(I->getInitializer());
|
||||
}
|
||||
|
||||
// Add all of the global variables to the value table...
|
||||
//
|
||||
for_each(TheModule->gbegin(), TheModule->gend(),
|
||||
bind_obj(this, &SlotCalculator::insertValue));
|
||||
for(Module::const_giterator I = TheModule->gbegin(), E = TheModule->gend();
|
||||
I != E; ++I)
|
||||
insertValue(I);
|
||||
|
||||
// Scavenge the types out of the functions, then add the functions themselves
|
||||
// to the value table...
|
||||
//
|
||||
for_each(TheModule->begin(), TheModule->end(), // Insert functions...
|
||||
bind_obj(this, &SlotCalculator::insertValue));
|
||||
for(Module::const_iterator I = TheModule->begin(), E = TheModule->end();
|
||||
I != E; ++I)
|
||||
insertValue(I);
|
||||
|
||||
// Insert constants that are named at module level into the slot pool so that
|
||||
// the module symbol table can refer to them...
|
||||
|
@ -132,8 +130,8 @@ void SlotCalculator::incorporateFunction(const Function *M) {
|
|||
SC_DEBUG("Inserting function arguments\n");
|
||||
|
||||
// Iterate over function arguments, adding them to the value table...
|
||||
for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
|
||||
bind_obj(this, &SlotCalculator::insertValue));
|
||||
for(Function::const_aiterator I = M->abegin(), E = M->aend(); I != E; ++I)
|
||||
insertValue(I);
|
||||
|
||||
// Iterate over all of the instructions in the function, looking for constant
|
||||
// values that are referenced. Add these to the value pools before any
|
||||
|
@ -166,8 +164,10 @@ void SlotCalculator::incorporateFunction(const Function *M) {
|
|||
SC_DEBUG("Inserting Labels:\n");
|
||||
|
||||
// Iterate over basic blocks, adding them to the value table...
|
||||
for_each(M->begin(), M->end(),
|
||||
bind_obj(this, &SlotCalculator::insertValue));
|
||||
for (Function::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
insertValue(I);
|
||||
/* for_each(M->begin(), M->end(),
|
||||
bind_obj(this, &SlotCalculator::insertValue));*/
|
||||
|
||||
SC_DEBUG("Inserting Instructions:\n");
|
||||
|
||||
|
|
|
@ -5,10 +5,9 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include "llvm/InstrTypes.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/InstrTypes.h"
|
||||
#include "Support/StringExtras.h"
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
//===-- llvm/SymbolTableListTraitsImpl.h - Implementation ------*- C++ -*--===//
|
||||
//
|
||||
// This file implements the stickier parts of the SymbolTableListTraits class,
|
||||
// and is explicitly instantiated where needed to avoid defining all this code
|
||||
// in a widely used header.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SYMBOLTABLELISTTRAITS_IMPL_H
|
||||
#define LLVM_SYMBOLTABLELISTTRAITS_IMPL_H
|
||||
|
||||
#include "llvm/SymbolTableListTraits.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
|
||||
template<typename ValueSubClass, typename ItemParentClass,typename SymTabClass,
|
||||
typename SubClass>
|
||||
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||
::setParent(SymTabClass *STO) {
|
||||
iplist<ValueSubClass> &List = SubClass::getList(ItemParent);
|
||||
|
||||
// Remove all of the items from the old symtab..
|
||||
if (SymTabObject && !List.empty()) {
|
||||
SymbolTable *SymTab = SymTabObject->getSymbolTable();
|
||||
for (iplist<ValueSubClass>::iterator I = List.begin(); I != List.end(); ++I)
|
||||
if (I->hasName()) SymTab->remove(I);
|
||||
}
|
||||
|
||||
SymTabObject = STO;
|
||||
|
||||
// Add all of the items to the new symtab...
|
||||
if (SymTabObject && !List.empty()) {
|
||||
SymbolTable *SymTab = SymTabObject->getSymbolTableSure();
|
||||
for (iplist<ValueSubClass>::iterator I = List.begin(); I != List.end(); ++I)
|
||||
if (I->hasName()) SymTab->insert(I);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
|
||||
typename SubClass>
|
||||
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||
::addNodeToList(ValueSubClass *V) {
|
||||
assert(V->getParent() == 0 && "Value already in a container!!");
|
||||
V->setParent(ItemParent);
|
||||
if (V->hasName() && SymTabObject)
|
||||
SymTabObject->getSymbolTableSure()->insert(V);
|
||||
}
|
||||
|
||||
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
|
||||
typename SubClass>
|
||||
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||
::removeNodeFromList(ValueSubClass *V) {
|
||||
V->setParent(0);
|
||||
if (V->hasName() && SymTabObject)
|
||||
SymTabObject->getSymbolTable()->remove(V);
|
||||
}
|
||||
|
||||
template<typename ValueSubClass, typename ItemParentClass, typename SymTabClass,
|
||||
typename SubClass>
|
||||
void SymbolTableListTraits<ValueSubClass,ItemParentClass,SymTabClass,SubClass>
|
||||
::transferNodesFromList(iplist<ValueSubClass, ilist_traits<ValueSubClass> > &L2,
|
||||
ilist_iterator<ValueSubClass> first,
|
||||
ilist_iterator<ValueSubClass> last) {
|
||||
// We only have to do work here if transfering instructions between BB's
|
||||
ItemParentClass *NewIP = ItemParent, *OldIP = L2.ItemParent;
|
||||
if (NewIP == OldIP) return; // No work to do at all...
|
||||
|
||||
// We only have to update symbol table entries if we are transfering the
|
||||
// instructions to a different symtab object...
|
||||
SymTabClass *NewSTO = SymTabObject, *OldSTO = L2.SymTabObject;
|
||||
if (NewSTO != OldSTO) {
|
||||
for (; first != last; ++first) {
|
||||
ValueSubClass &V = *first;
|
||||
bool HasName = V.hasName();
|
||||
if (OldSTO && HasName)
|
||||
OldSTO->getSymbolTable()->remove(&V);
|
||||
V.setParent(NewIP);
|
||||
if (NewSTO && HasName)
|
||||
NewSTO->getSymbolTableSure()->insert(&V);
|
||||
}
|
||||
} else {
|
||||
// Just transfering between blocks in the same function, simply update the
|
||||
// parent fields in the instructions...
|
||||
for (; first != last; ++first)
|
||||
first->setParent(NewIP);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,222 +0,0 @@
|
|||
//===-- llvm/ValueHolderImpl.h - Implement ValueHolder template --*- C++ -*--=//
|
||||
//
|
||||
// This file implements the ValueHolder class. This is kept out of line because
|
||||
// it tends to pull in a lot of dependencies on other headers and most files
|
||||
// don't need all that crud.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_VALUEHOLDER_IMPL_H
|
||||
#define LLVM_VALUEHOLDER_IMPL_H
|
||||
|
||||
#include "llvm/ValueHolder.h"
|
||||
#include "llvm/SymbolTable.h"
|
||||
#include <algorithm>
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
void ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::setParent(SymTabType *P) {
|
||||
if (Parent && !empty()) { // Remove all of the items from the old symtab..
|
||||
SymbolTable *SymTab = Parent->getSymbolTable();
|
||||
for (iterator I = begin(); I != end(); ++I)
|
||||
if ((*I)->hasName()) SymTab->remove(*I);
|
||||
}
|
||||
|
||||
Parent = P;
|
||||
|
||||
if (Parent && !empty()) { // Add all of the items to the new symtab...
|
||||
SymbolTable *SymTab = Parent->getSymbolTableSure();
|
||||
for (iterator I = begin(); I != end(); ++I)
|
||||
if ((*I)->hasName()) SymTab->insert(*I);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
void ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::remove(ValueSubclass *D) {
|
||||
iterator I(find(begin(), end(), D));
|
||||
assert(I != end() && "Value not in ValueHolder!!");
|
||||
remove(I);
|
||||
}
|
||||
|
||||
// ValueHolder::remove(iterator &) this removes the element at the location
|
||||
// specified by the iterator, and leaves the iterator pointing to the element
|
||||
// that used to follow the element deleted.
|
||||
//
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
ValueSubclass *ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::remove(iterator &DI) {
|
||||
assert(DI != ValueList.end() &&
|
||||
"Trying to remove the end of the value list!!!");
|
||||
|
||||
ValueSubclass *i = *DI;
|
||||
DI = ValueList.erase(DI);
|
||||
|
||||
i->setParent(0); // I don't own you anymore... byebye...
|
||||
|
||||
// You don't get to be in the symbol table anymore... byebye
|
||||
if (i->hasName() && Parent)
|
||||
Parent->getSymbolTable()->remove(i);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
ValueSubclass *ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::pop_back() {
|
||||
assert(!ValueList.empty() && "Can't pop_back an empty valuelist!");
|
||||
ValueSubclass *i = ValueList.back();
|
||||
ValueList.pop_back();
|
||||
i->setParent(0); // I don't own you anymore... byebye...
|
||||
|
||||
// You don't get to be in the symbol table anymore... byebye
|
||||
if (i->hasName() && Parent)
|
||||
Parent->getSymbolTable()->remove(i);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
ValueSubclass *ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::remove(const iterator &DI) {
|
||||
assert(DI != ValueList.end() &&
|
||||
"Trying to remove the end of the value holder list!!!");
|
||||
|
||||
ValueSubclass *i = *DI;
|
||||
ValueList.erase(DI);
|
||||
|
||||
i->setParent(0); // I don't own you anymore... byebye...
|
||||
|
||||
// You don't get to be in the symbol table anymore... byebye
|
||||
if (i->hasName() && Parent)
|
||||
Parent->getSymbolTable()->remove(i);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
void ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::remove(iterator S, iterator E) {
|
||||
for (iterator I = S; I != E; ++I) {
|
||||
ValueSubclass *i = *I;
|
||||
i->setParent(0); // I don't own you anymore... byebye...
|
||||
|
||||
// You don't get to be in the symbol table anymore... byebye
|
||||
if (i->hasName() && Parent)
|
||||
Parent->getSymbolTable()->remove(i);
|
||||
}
|
||||
|
||||
ValueList.erase(S, E);
|
||||
}
|
||||
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
ValueSubclass *ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::replaceWith(iterator &DI, ValueSubclass *NewVal) {
|
||||
assert(DI != ValueList.end() &&
|
||||
"Trying to replace the end of the value holder list!!!");
|
||||
|
||||
// Remove the value from the current container...
|
||||
ValueSubclass *Ret = *DI;
|
||||
Ret->setParent(0); // I don't own you anymore... byebye...
|
||||
|
||||
// You don't get to be in the symbol table anymore... byebye
|
||||
if (Ret->hasName() && Parent)
|
||||
Parent->getSymbolTable()->remove(Ret);
|
||||
|
||||
// Insert the new value into the container...
|
||||
assert(NewVal->getParent() == 0 && "Value already has parent!");
|
||||
NewVal->setParent(ItemParent);
|
||||
|
||||
*DI = NewVal;
|
||||
if (NewVal->hasName() && Parent)
|
||||
Parent->getSymbolTableSure()->insert(NewVal);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
void ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::push_front(ValueSubclass *Inst) {
|
||||
assert(Inst->getParent() == 0 && "Value already has parent!");
|
||||
Inst->setParent(ItemParent);
|
||||
|
||||
//ValueList.push_front(Inst);
|
||||
ValueList.insert(ValueList.begin(), Inst);
|
||||
|
||||
if (Inst->hasName() && Parent)
|
||||
Parent->getSymbolTableSure()->insert(Inst);
|
||||
}
|
||||
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
void ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::push_back(ValueSubclass *Inst) {
|
||||
assert(Inst->getParent() == 0 && "Value already has parent!");
|
||||
Inst->setParent(ItemParent);
|
||||
|
||||
ValueList.push_back(Inst);
|
||||
|
||||
if (Inst->hasName() && Parent)
|
||||
Parent->getSymbolTableSure()->insert(Inst);
|
||||
}
|
||||
|
||||
// ValueHolder::insert - This method inserts the specified value *BEFORE* the
|
||||
// indicated iterator position, and returns an interator to the newly inserted
|
||||
// value.
|
||||
//
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
ValueHolder<ValueSubclass,ItemParentType,SymTabType>::iterator
|
||||
ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::insert(iterator Pos, ValueSubclass *Inst) {
|
||||
assert(Inst->getParent() == 0 && "Value already has parent!");
|
||||
Inst->setParent(ItemParent);
|
||||
|
||||
iterator I = ValueList.insert(Pos, Inst);
|
||||
if (Inst->hasName() && Parent)
|
||||
Parent->getSymbolTableSure()->insert(Inst);
|
||||
return I;
|
||||
}
|
||||
|
||||
// ValueHolder::insert - This method inserts the specified _range_ of values
|
||||
// before the 'Pos' iterator, and returns an iterator to the first newly
|
||||
// inserted element. This currently only works for vector iterators...
|
||||
//
|
||||
// FIXME: This is not generic so that the code does not have to be around
|
||||
// to be used... is this ok?
|
||||
//
|
||||
template<class ValueSubclass, class ItemParentType, class SymTabType>
|
||||
ValueHolder<ValueSubclass,ItemParentType,SymTabType>::iterator
|
||||
ValueHolder<ValueSubclass,ItemParentType,SymTabType>
|
||||
::insert(iterator Pos, // Where to insert
|
||||
iterator First, iterator Last) { // Vector to read insts from
|
||||
|
||||
// Since the vector range insert operation doesn't return an updated iterator,
|
||||
// we have to convert the iterator to and index and back to assure that it
|
||||
// cannot get invalidated. Gross hack, but effective.
|
||||
//
|
||||
unsigned Offset = Pos-begin();
|
||||
|
||||
// Check to make sure that the values are not already in some valueholder...
|
||||
for (iterator X = First; X != Last; ++X) {
|
||||
assert((*X)->getParent() == 0 &&
|
||||
"Cannot insert into valueholder, value already has a parent!");
|
||||
(*X)->setParent(ItemParent);
|
||||
}
|
||||
|
||||
// Add all of the values to the value holder...
|
||||
ValueList.insert(Pos, First, Last);
|
||||
|
||||
// Insert all of the instructions in the symbol table...
|
||||
if (Parent)
|
||||
for (;First != Last; ++First)
|
||||
if ((*First)->hasName())
|
||||
Parent->getSymbolTableSure()->insert(*First);
|
||||
|
||||
return begin()+Offset;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -7,10 +7,7 @@
|
|||
|
||||
#include "llvm/iTerminators.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#ifndef NDEBUG
|
||||
#include "llvm/Type.h" // Only used for assertions...
|
||||
#include <iostream>
|
||||
#endif
|
||||
#include "llvm/Type.h"
|
||||
|
||||
BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond)
|
||||
: TerminatorInst(Instruction::Br) {
|
||||
|
@ -24,14 +21,6 @@ BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond)
|
|||
|
||||
assert(!!False == !!Cond &&
|
||||
"Either both cond and false or neither can be specified!");
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (Cond != 0 && Cond->getType() != Type::BoolTy) {
|
||||
std::cerr << "Bad Condition: ";
|
||||
Cond->dump();
|
||||
std::cerr << "\n";
|
||||
}
|
||||
#endif
|
||||
assert((Cond == 0 || Cond->getType() == Type::BoolTy) &&
|
||||
"May only branch on boolean predicates!!!!");
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
|
||||
#include "llvm/iTerminators.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#ifndef NDEBUG
|
||||
#include "llvm/Type.h"
|
||||
#endif
|
||||
|
||||
SwitchInst::SwitchInst(Value *V, BasicBlock *DefDest)
|
||||
: TerminatorInst(Instruction::Switch) {
|
||||
|
|
|
@ -24,30 +24,29 @@ static cl::String ExtractFunc("func", "Specify function to extract", 0, "main");
|
|||
struct FunctionExtractorPass : public Pass {
|
||||
const char *getPassName() const { return "Function Extractor"; }
|
||||
|
||||
bool run(Module *M) {
|
||||
bool run(Module &M) {
|
||||
// Mark all global variables to be internal
|
||||
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
|
||||
(*I)->setInternalLinkage(true);
|
||||
for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
|
||||
I->setInternalLinkage(true);
|
||||
|
||||
Function *Named = 0;
|
||||
|
||||
// Loop over all of the functions in the module, dropping all references in
|
||||
// functions that are not the named function.
|
||||
for (Module::iterator I = M->begin(), E = M->end(); I != E;)
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E;)
|
||||
// Check to see if this is the named function!
|
||||
if (!Named && (*I)->getName() == ExtractFunc) {
|
||||
if (!Named && I->getName() == ExtractFunc) {
|
||||
// Yes, it is. Keep track of it...
|
||||
Named = *I;
|
||||
Named = I;
|
||||
|
||||
// Make sure it's globally accessable...
|
||||
Named->setInternalLinkage(false);
|
||||
|
||||
// Remove the named function from the module.
|
||||
M->getFunctionList().remove(I);
|
||||
E = M->end();
|
||||
M.getFunctionList().remove(I);
|
||||
} else {
|
||||
// Nope it's not the named function, delete the body of the function
|
||||
(*I)->dropAllReferences();
|
||||
I->dropAllReferences();
|
||||
++I;
|
||||
}
|
||||
|
||||
|
@ -57,27 +56,26 @@ struct FunctionExtractorPass : public Pass {
|
|||
// functions.
|
||||
std::vector<Function*> NewFunctions;
|
||||
|
||||
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
if (!(*I)->use_empty()) {
|
||||
Function *New = new Function((*I)->getFunctionType(), false,
|
||||
(*I)->getName());
|
||||
(*I)->replaceAllUsesWith(New);
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
||||
if (!I->use_empty()) {
|
||||
Function *New = new Function(I->getFunctionType(), false, I->getName());
|
||||
I->replaceAllUsesWith(New);
|
||||
NewFunctions.push_back(New);
|
||||
}
|
||||
|
||||
// Now the module only has unused functions with their references dropped.
|
||||
// Delete them all now!
|
||||
M->getFunctionList().delete_all();
|
||||
M.getFunctionList().clear();
|
||||
|
||||
// Re-insert the named function...
|
||||
if (Named)
|
||||
M->getFunctionList().push_back(Named);
|
||||
M.getFunctionList().push_back(Named);
|
||||
else
|
||||
std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n";
|
||||
|
||||
// Insert all of the function stubs...
|
||||
M->getFunctionList().insert(M->end(), NewFunctions.begin(),
|
||||
NewFunctions.end());
|
||||
M.getFunctionList().insert(M.end(), NewFunctions.begin(),
|
||||
NewFunctions.end());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -102,6 +100,6 @@ int main(int argc, char **argv) {
|
|||
Passes.add(createCleanupGCCOutputPass()); // Fix gccisms
|
||||
Passes.add(new WriteBytecodePass(&std::cout)); // Write bytecode to file...
|
||||
|
||||
Passes.run(M.get());
|
||||
Passes.run(*M.get());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ static inline string GetFileNameRoot(const string &InputFilename) {
|
|||
return outputFilename;
|
||||
}
|
||||
|
||||
static void insertTraceCodeFor(Module *M) {
|
||||
static void insertTraceCodeFor(Module &M) {
|
||||
PassManager Passes;
|
||||
|
||||
// Insert trace code in all functions in the module
|
||||
|
@ -70,7 +70,7 @@ static void insertTraceCodeFor(Module *M) {
|
|||
}
|
||||
|
||||
// Eliminate duplication in constant pool
|
||||
Passes.add(createDynamicConstantMergePass());
|
||||
Passes.add(createConstantMergePass());
|
||||
|
||||
// Run passes to insert and clean up trace code...
|
||||
Passes.run(M);
|
||||
|
@ -99,7 +99,7 @@ static void insertTraceCodeFor(Module *M) {
|
|||
// compile should still succeed, just the native linker will probably fail.
|
||||
//
|
||||
std::auto_ptr<Module> TraceRoutines(TraceModule);
|
||||
if (LinkModules(M, TraceRoutines.get(), &ErrorMessage))
|
||||
if (LinkModules(&M, TraceRoutines.get(), &ErrorMessage))
|
||||
cerr << "Warning: Error linking in trace routines: "
|
||||
<< ErrorMessage << "\n";
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ static void insertTraceCodeFor(Module *M) {
|
|||
} else {
|
||||
cerr << "Emitting trace code to '" << TraceFilename
|
||||
<< "' for comparison...\n";
|
||||
WriteBytecodeToFile(M, Out);
|
||||
WriteBytecodeToFile(&M, Out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (TraceValues != TraceOff) // If tracing enabled...
|
||||
insertTraceCodeFor(M.get()); // Hack up module before using passmanager...
|
||||
insertTraceCodeFor(*M.get()); // Hack up module before using passmanager...
|
||||
|
||||
// Build up all of the passes that we want to do to the module...
|
||||
PassManager Passes;
|
||||
|
@ -208,7 +208,7 @@ int main(int argc, char **argv) {
|
|||
Target.addPassesToEmitAssembly(Passes, *Out);
|
||||
|
||||
// Run our queue of passes all at once now, efficiently.
|
||||
Passes.run(M.get());
|
||||
Passes.run(*M.get());
|
||||
|
||||
if (Out != &std::cout) delete Out;
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ int main(int argc, char **argv) {
|
|||
Passes.add(new WriteBytecodePass(Out, Out != &std::cout));
|
||||
|
||||
// Now that we have all of the passes ready, run them.
|
||||
if (Passes.run(M.get()) && !Quiet)
|
||||
if (Passes.run(*M.get()) && !Quiet)
|
||||
cerr << "Program modified.\n";
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue