⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glob_priv.cc

📁 c到DHL的转换工具
💻 CC
字号:
/* file "glob_priv.cc" *//*  Copyright (c) 1994 Stanford University    All rights reserved.    This software is provided under the terms described in    the "suif_copyright.h" include file. */#include <suif_copyright.h>/* code to help privatize global variables through procedure calls for * the porky program for SUIF */#define RCS_BASE_FILE glob_priv_cc#include "porky.h"RCS_BASE(    "$Id: glob_priv.cc,v 1.2 1999/08/25 03:27:29 brm Exp $")/*----------------------------------------------------------------------*    Begin Constant Declarations *----------------------------------------------------------------------*//*----------------------------------------------------------------------*    End Constant Declarations *----------------------------------------------------------------------*//*----------------------------------------------------------------------*    Begin Type Declarations *----------------------------------------------------------------------*/struct var_pair  {    var_sym *old_var;    var_sym *new_var;    boolean operator==(const var_pair &) const  { return FALSE; }  };DECLARE_LIST_CLASS(var_pair_list, var_pair);/*----------------------------------------------------------------------*    End Type Declarations *----------------------------------------------------------------------*//*----------------------------------------------------------------------*    Begin Private Global Variables *----------------------------------------------------------------------*/static char *k_possible_global_privatizable;/*----------------------------------------------------------------------*    End Private Global Variables *----------------------------------------------------------------------*//*----------------------------------------------------------------------*    Begin Private Function Declarations *----------------------------------------------------------------------*/static void fix_callsites_on_node(tree_node *the_node, void *);static void fix_callsites_on_instr(instruction *the_instr);static void fix_possible_callsite(instruction *the_instr);static void fix_callsite(in_cal *the_call, immed_list *privatize_immeds);static void substitute_in_callee_on_node(tree_node *the_node, void *data);static void substitute_in_callee_on_instr(instruction *the_instr,                                          var_pair_list *substitutions);static var_sym *sub_translate(var_sym *old_var, var_pair_list *substitutions);/*----------------------------------------------------------------------*    End Private Function Declarations *----------------------------------------------------------------------*//*----------------------------------------------------------------------*    Begin Public Function Implementations *----------------------------------------------------------------------*/extern void init_glob_priv(void)  {    ANNOTE(k_possible_global_privatizable, "possible global privatizable",           TRUE);  }extern void glob_priv_on_proc(tree_proc *the_proc)  {    the_proc->map(&fix_callsites_on_node, NULL);    annote *glob_priv_annote =            the_proc->proc()->annotes()->peek_annote(                    k_possible_global_privatizable);    if (glob_priv_annote == NULL)        return;    immed_list *privatize_immeds = glob_priv_annote->immeds();    var_pair_list substitutions;    immed_list_iter privatize_iter(privatize_immeds);    while (!privatize_iter.is_empty())      {        immed this_immed = privatize_iter.step();        if ((!this_immed.is_symbol()) || (!this_immed.offset() == 0))          {            error_line(1, NULL, "badly formed \"%s\" annote",                       k_possible_global_privatizable);          }        sym_node *this_sym = this_immed.symbol();        if (!this_sym->is_var())          {            error_line(1, NULL, "badly formed \"%s\" annote",                       k_possible_global_privatizable);          }        var_sym *old_var = (var_sym *)this_sym;        ptr_type *new_ptr = new ptr_type(old_var->type());        if (the_proc->proc()->src_lang() == src_fortran)            new_ptr->append_annote(k_call_by_ref, NULL);        type_node *new_type = old_var->type()->parent()->install_type(new_ptr);        var_sym *new_var =                the_proc->proc_syms()->new_var(new_type, old_var->name());        new_var->set_param();        the_proc->proc_syms()->params()->append(new_var);        var_pair new_pair;        new_pair.old_var = old_var;        new_pair.new_var = new_var;        substitutions.append(new_pair);      }    the_proc->map(&substitute_in_callee_on_node, &substitutions);  }/*----------------------------------------------------------------------*    End Public Function Implementations *----------------------------------------------------------------------*//*----------------------------------------------------------------------*    Begin Private Function Implementations *----------------------------------------------------------------------*/static void fix_callsites_on_node(tree_node *the_node, void *)  {    if (the_node->is_instr())      {        tree_instr *the_tree_instr = (tree_instr *)the_node;        instruction *the_instr = the_tree_instr->instr();        fix_callsites_on_instr(the_instr);      }  }static void fix_callsites_on_instr(instruction *the_instr)  {    fix_possible_callsite(the_instr);    unsigned num_srcs = the_instr->num_srcs();    for (unsigned src_num = 0; src_num < num_srcs; ++src_num)      {        operand this_src = the_instr->src_op(src_num);        if (this_src.is_expr())            fix_callsites_on_instr(this_src.instr());      }  }static void fix_possible_callsite(instruction *the_instr)  {    if (the_instr->opcode() == io_cal)      {        in_cal *the_call = (in_cal *)the_instr;        proc_sym *call_proc = proc_for_call(the_call);        if (call_proc != NULL)          {            annote *glob_priv_annote =                    call_proc->annotes()->peek_annote(                            k_possible_global_privatizable);            if (glob_priv_annote != NULL)                fix_callsite(the_call, glob_priv_annote->immeds());          }      }  }static void fix_callsite(in_cal *the_call, immed_list *privatize_immeds)  {    int additional_args = privatize_immeds->count();    unsigned old_num_args = the_call->num_args();    unsigned new_num_args = old_num_args + additional_args;    the_call->set_num_args(new_num_args);    immed_list_iter immed_iter(privatize_immeds);    for (unsigned arg_num = old_num_args; arg_num < new_num_args; ++arg_num)      {        assert(!immed_iter.is_empty());        immed this_immed = immed_iter.step();        if ((!this_immed.is_symbol()) || (!this_immed.offset() == 0))          {            error_line(1, NULL, "badly formed \"%s\" annote",                       k_possible_global_privatizable);          }        sym_node *this_sym = this_immed.symbol();        if (!this_sym->is_var())          {            error_line(1, NULL, "badly formed \"%s\" annote",                       k_possible_global_privatizable);          }        var_sym *this_var = (var_sym *)this_sym;        in_ldc *new_ldc =                new in_ldc(this_var->type()->unqual()->ptr_to(), operand(),                           this_immed);        this_var->set_addr_taken();        the_call->set_argument(arg_num, operand(new_ldc));      }    assert(immed_iter.is_empty());  }static void substitute_in_callee_on_node(tree_node *the_node, void *data)  {    var_pair_list *substitutions = (var_pair_list *)data;    switch (the_node->kind())      {        case TREE_INSTR:          {            tree_instr *the_tree_instr = (tree_instr *)the_node;            substitute_in_callee_on_instr(the_tree_instr->instr(),                                          substitutions);            break;          }        case TREE_FOR:          {            tree_for *the_for = (tree_for *)the_node;            /*             * In general, we don't know what annotations mean so we             * don't know if after the transformations they should             * refer to the global or to the new parameter (or it             * might be that the annotation doesn't even apply after             * the tranformation).  So generally we assume that we're             * not trying to preserve the information in annotations.             * The one class of annotation we do have to worry about             * though is the class of annotations giving             * parallelization information to skweel (after all, this             * pass is supposed to prepare the code for skweel after             * the annotations describing parallelism have been             * added).  For these annotations on tree_for nodes, such             * as "privatized" and "reduced" (this happens when there             * is a parallel loop in a procedure called in another             * parallel loop), the annotations must be changed to             * point to the parameter.             */            replacements the_replacements;            var_pair_list_iter sub_iter(substitutions);            while (!sub_iter.is_empty())              {                var_pair this_pair = sub_iter.step();                the_replacements.oldsyms.append(this_pair.old_var);                the_replacements.newsyms.append(this_pair.new_var);              }            the_for->clone_annotes(the_for, &the_replacements, TRUE);            var_sym *old_index = the_for->index();            var_sym *replacement = sub_translate(old_index, substitutions);            if (replacement != NULL)              {                var_sym *new_index =                        the_for->scope()->new_unique_var(old_index->type());                the_for->set_index(new_index);                in_rrr *new_store =                        new in_rrr(io_str, type_void, operand(),                                   operand(replacement), operand(new_index));                the_for->body()->append(new tree_instr(new_store->clone()));                the_for->parent()->insert_after(new tree_instr(new_store),                                                the_for->list_e());              }            break;          }        default:            break;      }  }static void substitute_in_callee_on_instr(instruction *the_instr,                                          var_pair_list *substitutions)  {    if (the_instr->dst_op().is_symbol())      {        var_sym *dest_var = the_instr->dst_op().symbol();        var_sym *replacement = sub_translate(dest_var, substitutions);        if (replacement != NULL)          {            tree_instr *the_tree_instr = the_instr->parent();            assert(the_tree_instr->instr() == the_instr);            the_tree_instr->remove_instr(the_instr);            the_instr->set_dst(operand());            in_rrr *new_store =                    new in_rrr(io_str, type_void, operand(),                               operand(replacement), operand(the_instr));            the_tree_instr->set_instr(new_store);          }      }    if (the_instr->opcode() == io_ldc)      {        in_ldc *the_ldc = (in_ldc *)the_instr;        immed value = the_ldc->value();        if (value.is_symbol() && value.symbol()->is_var())          {            var_sym *the_var = (var_sym *)(value.symbol());            var_sym *replacement = sub_translate(the_var, substitutions);            if (replacement != NULL)              {                replace_instruction_with_operand(the_ldc,                                                 operand(replacement));                delete the_ldc;              }          }        return;      }    unsigned num_srcs = the_instr->num_srcs();    for (unsigned src_num = 0; src_num < num_srcs; ++src_num)      {        operand this_src = the_instr->src_op(src_num);        if (this_src.is_symbol())          {            var_sym *src_var = this_src.symbol();            var_sym *replacement = sub_translate(src_var, substitutions);            if (replacement != NULL)              {                in_rrr *new_load =                        new in_rrr(io_lod, src_var->type()->unqual(),                                   operand(), operand(replacement));                the_instr->set_src_op(src_num, operand(new_load));              }          }        else if (this_src.is_expr())          {            substitute_in_callee_on_instr(this_src.instr(), substitutions);          }      }  }static var_sym *sub_translate(var_sym *old_var, var_pair_list *substitutions)  {    var_pair_list_iter the_iter(substitutions);    while (!the_iter.is_empty())      {        var_pair this_pair = the_iter.step();        if (this_pair.old_var == old_var)            return this_pair.new_var;      }    return NULL;  }/*----------------------------------------------------------------------*    End Private Function Implementations *----------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -