
struct AutoRefactor
{
    AutoRefactor(Node *&root)
    {
        for(int i = 0; ; i++)
        {
            ASSERT(i<100);
            sys->codechanged = false;

            // Apply rule 2b iteratively: find duplicates, and make into a function at LCA

            for(;;) try
            {
                ASSERT(!root->IterSame(root));                      // root can't be a match for itself
                break;
            }
            catch(Node *newroot)
            {
                if(newroot)
                    root = newroot;
                sys->codechanged = true;
            }

            // Apply rule 2a iteratively: find placeholders that have a similar context

            for(;;) try
            {
                root->IterContexts();
                break;
            }
            catch(Node *)
            {
                sys->codechanged = true;
            }

            // Apply rule 3: Merge small functions (created by 2a/b) into bigger ones

            root->FunctionMerger();

            // Inline functions

            Node *rep = root->Inliner();
            if(rep)
            {
                delete root;
                root = rep;
            }

            if(!sys->codechanged) break;
        }
    }
};
