📄 glob_priv.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 + -