!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: nginx/1.23.4. PHP/5.6.40-65+ubuntu20.04.1+deb.sury.org+1 

uname -a: Linux foro-restaurado-2 5.15.0-1040-oracle #46-Ubuntu SMP Fri Jul 14 21:47:21 UTC 2023
aarch64
 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/home/scripts/pba/phc-read-only/src/optimize/   drwxrwxr-x
Free 83.21 GB of 96.73 GB (86.02%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     Dead_code_elimination.cpp (9.21 KB)      -rw-rw-r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#include "Dead_code_elimination.h" // TODO: rename file
#include "process_ir/General.h"
#include "Def_use_web.h"
#include "assert.h"
#include "embed/embed.h"
#include "Oracle.h"

using namespace MIR;
using namespace boost;

DCE::DCE ()
{
}

// TODO: move this to Oracle
bool is_pure (Expr* in)
{
    // TODO: use Whole_program for this, and mark user-functions according to
    // whether they do something impure (except uses and defs).
    Wildcard<METHOD_NAME>* name = new Wildcard<METHOD_NAME>;
    if (in->match (new Method_invocation (NULL, name, NULL))
        && Oracle::is_pure_function (name->value))
        return true;

    return (not (isa<New> (in) || isa<Method_invocation> (in)));
}

/*
 * Does the statement have any externally visible effects (like IO)?
 *        Has visible effects:
 *            Any function we dont know anything about
 *            TODO: impure functions dont necessarily have them (ie array_merge)
 *            Any class instatiation
 *
 *         Doesn't have visible effects
 *            Anything else
 *
 *    Whether or not this touches reference parameters is modelled with a MU in
 *    the block exit, so it can be safely ignored here.
*/
bool is_critical (Statement* in)
{
    // TODO: this is only critical if its result is used.
    if (isa<Return> (in))
        return true;

    // Foreach_end is needed every time the Foreach_reset is present. So treat
    // it specially.
    // TODO: is there a way to handle this without special casing it?
    // TODO: just mark the foreach_* nodes which write as critical.
    // TODO: rethink this. We should be able to remove unused blocks entirely.
    if (    isa<Foreach_reset> (in)
        || isa<Foreach_next> (in)
        || isa<Foreach_end> (in))
        return true;

    // TODO: these can cause side-effecting functions such as __get or __set.
    // Function calls
    Wildcard<Expr>* expr = new Wildcard<Expr>;
    if (in->match (new Eval_expr (expr))
        || in->match (
            new Assign_var (
                new Wildcard<VARIABLE_NAME>,
                false, // dont-care
                expr)))
    {
        return !is_pure (expr->value);
    }
    else
        return false;
}

bool
is_bb_critical (Basic_block* bb)
{
    if (Statement_block* sb = dynamic_cast<Statement_block*> (bb))
        return (is_critical (sb->statement));

    if (isa<Exit_block> (bb) || isa<Entry_block> (bb))
        return true;

    return false;
}

/*
 * Cooper/Torczon, Sec. 10.3.1 and Figure 10.3
 *        http://www.cs.rice.edu/~keith/512/Lectures/10DeadCprop.pdf
 *
 *    Has a mark-sweep-style DCE algorithm: (based on Cytron et al SSA paper,
 *    section 7.1)
 *
 *    Dead ():
 *        MarkPass ()
 *        SweepPass ()
 */

/*    MarkPass ():
 *
 *        Worklist = []
 *
 *        // works on statements only: Phis cant be critical
 *        foreach statement S
 *            clear s.mark
 *            if s is critical
 *                set s.mark
 *                worklist []= s
 *
 *        // Works on phis and statements.
 *        while !worklist.empty ()
 *            i = worklist.pop_front ()
 *            foreach u in i.uses ()
 *                d = u.def ()
 *                if (!d.mark)
 *                    set d.mark
 *                    worklist []= d
 *
 *            foreach bb in s.rdf ()
 *                j = bb.branch ()
 *                if j.mark:
 *                    set j.mark
 *                    worklist =[] j
 */
void
DCE::mark_pass ()
{
    // Initialize the critical blocks - a critical block is a side-effecting
    // statement.

    // We don't have any information with which to mark assignments affecting
    // reference parameters. However, these are covered since the Exit_block
    // is critical, and it uses all reference parameters. This creates
    // may-uses for all the aliases, which transitively follows CHI nodes,
    // ensuring that assignments are marked as critical.

    dump ();
    foreach (Basic_block* bb, *cfg->get_all_bbs ())
    {
        if (is_bb_critical (bb))
        {
            mark_entire_block (bb, "as critical");
        }
    }

    dump ();

    // Go through the worklist, propagating the mark from uses to defs
    while (worklist->size () > 0)
    {
        SSA_def* def = worklist->front ();
        worklist->pop_front ();
        DEBUG ("\nProcessing ");
        def->dump ();

        foreach (SSA_use* use, *def->get_uses ())
        {
            if (use->type_flag != SSA_PHI)
                mark_def (use);
        }
    }

    // Special case for Foreach_end: If its defining reset isnt marked, unmark it.
    foreach (Basic_block* bb, *cfg->get_all_bbs ())
    {
        Foreach_end* fe = NULL;
        Foreach_reset* fr = NULL;
        Statement_block *sb, *sdom;
        if ((sb = dynamic_cast<Statement_block*> (bb))
            && (fe = dynamic_cast<Foreach_end*> (sb->statement)))
        {
            // Find the Foreach_reset, which must dominate it.
            bool found = false;
            Basic_block* dom = bb;
            while ((dom = dom->get_immediate_dominator ()))
            {
                if ((sdom = dynamic_cast<Statement_block*> (dom))
                    && (fr = dynamic_cast<Foreach_reset*> (sdom->statement)))
                {
                    if (fr->iter->equals (fe->iter))
                    {
                        if (!is_marked (dom))
                            unmark_block (bb);

                        found = true;
                        break;
                    }
                }
            }
            assert (found);
        }
    }
}

void
DCE::mark_entire_block (Basic_block* bb, string why)
{
    if (bb_marks[bb->ID])
        return;

    DEBUG ("marking " << bb->ID << " " << why);
    bb_marks [bb->ID] = true;

    // Note there are no may-defs here. They're already divided into defs or
    // uses. Also, "entire block" doesnt include Phis.

    foreach (SSA_use* use, *bb->cfg->duw->get_block_uses (bb))
    {
        if (use->type_flag != SSA_PHI)
            mark_def (use);
    }
    foreach (SSA_def* def, *bb->cfg->duw->get_block_defs (bb))
    {
        if (def->type_flag != SSA_PHI)
            mark (def, "");
    }
    // Mark the critical branches (ie, the reverse dominance frontier of
    // the critical blocks: The dominance frontier occurs at joins. The
    // reverse-dominance frontier is therefore at splits, which must be
    // branches). They are marked as they are required for control flow to
    // reach this point. They are just as important for phis as they are for
    // other statements, and we mark the branch, not the phi.
    mark_rdf (bb);
}

void
DCE::mark_rdf (Basic_block* bb)
{
    foreach (Basic_block* rdf, *bb->get_reverse_dominance_frontier ())
    {
        mark_entire_block (rdf, "as part of " + lexical_cast<string>(bb->ID) + "'s RDF"); 
    }
}

void
DCE::mark (SSA_def* def, string why)
{
    assert (def->type_flag != SSA_PHI);        //Not 100% sure if this assertion is correct, think so though

    if (marks[def])
    {
        return;
    }
        
    DEBUG ("marking ");
    def->dump();
    DEBUG (why);

    marks[def] = true;

    // TODO: really we should be marking the def but not the CHI, but its not
    // set up well for that at the moment.
    mark_entire_block (def->bb, "");

    worklist->push_back (def);
}

void
DCE::mark_def (SSA_use* use)
{
    if (use->get_defs ()->size () == 1)
    {
        SSA_def* def = use->get_defs ()->front ();
        if (marks[def])
            return;

        // When a def which is a phi node is marked, we need to mark it's arguments also
        if (def->type_flag == SSA_PHI)
        {
            // Here I'm making the assumption that the RDF of a phi node whose arguments we're marking 
            // doesn't need to be marked.  This could be wrong however...
            
            marks[def] = true;        //should I call mark () here?  Probably... I'd need to change mark () though.. TODO
            foreach (SSA_name* phi_arg, *def->bb->get_phi_args (*def->name))
            {
                if (phi_arg->str () != use->name->str ())
                {
                    if (phi_arg->get_version ())            
                    {
                        if (def->bb->cfg->duw->get_named_uses (phi_arg)->size ())
                        {
                            SSA_use* arg_use = def->bb->cfg->duw->get_named_uses (phi_arg)->front ();
                            mark_def (arg_use);    
                        }    
                    }    
                }
            }
        }    
        else
            mark (def, "due to def of " + use->name->str ());
        
    }    

}

void
DCE::unmark_block (Basic_block* bb)
{
    bb_marks [bb->ID] = false;
}

// Check if the block is marked (ignoring the phi nodes)
bool
DCE::is_marked (Basic_block* bb)
{
    if (isa<Entry_block> (bb) || isa<Exit_block> (bb) || isa<Empty_block> (bb))
        return true;

    return bb_marks [bb->ID];
}

/*    SweepPass ():
 *        foreach operation i: // i can be a phi or a statement
 *            if !i.mark
 *                if isa<Branch> (i)
 *                    i = jump to nearest marked post-dominator
 *                else
 *                    delete i
 */
void
DCE::sweep_pass ()
{
    DEBUG("START SWEEP PASS");

    // TODO: Verify if the below code for removing phis is in anyway useful 
    //    (I think the ones we remove will just not get recreated when the DUW is rebuilt)
    foreach (Basic_block* bb, *cfg->get_all_bbs ())
    {
        // Remove the phi nodes first, since the BB* may be replaced with an
        // Empty BB.
        foreach (SSA_name phi_lhs, *bb->get_phi_lhss ())
        {
            if (!marks[new SSA_def (bb, &phi_lhs,SSA_PHI)])
                bb->remove_phi_node (phi_lhs);
        }
    }

    foreach (Basic_block* bb, *cfg->get_all_bbs ())
    {
        if (is_marked (bb))
            continue;

        DEBUG (bb->ID << " is not marked");

        if (isa<Statement_block> (bb))
        {
            cfg->remove_bb (bb);
            DEBUG ("REMOVED " << bb->ID);
            CTS ("num_blocks_removed");
        }

        else if (isa<Branch_block> (bb))
        {
            // find the nearest marked post-dominator
            Basic_block* postdominator = bb;
            while (!is_marked (postdominator))
                postdominator = postdominator->get_immediate_reverse_dominator ();

            cfg->remove_branch (dyc<Branch_block> (bb), postdominator);
            DEBUG ("REMOVED BRANCH " << bb->ID << " NEAREST MARKED POSTDOMINATOR: " << postdominator->ID);
            CTS ("num_blocks_removed");
        }
    }

    // TODO: we have enough information to manipulate the BBs to based on the
    // CHIs which are still live.
}

void
DCE::run (CFG* cfg)
{
    DEBUG ("START DCE");
    marks.clear ();
    bb_marks.clear ();

    worklist = new SSA_def_list;
    this->cfg = cfg;

    mark_pass ();
    dump ();
    sweep_pass ();
    dump ();
}

void
DCE::dump()
{
    CHECK_DEBUG ();
    DEBUG ("DCE:");
    foreach (Basic_block* bb, *cfg->get_all_bbs ())
        DEBUG (bb->ID << ": " << is_marked (bb));
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by HackingTool | HackingTool | Generation time: 0.0044 ]--