/* Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, Mountain View, CA 94043, or: http://www.sgi.com For further information regarding this notice, see: http://oss.sgi.com/projects/GenInfo/NoticeExplan */ /* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */ #ifndef be_symtab_INCLUDED #define be_symtab_INCLUDED #ifndef cmplr_segmented_array_INCLUDED #include "cmplr_segmented_array.h" #endif // cmplr_segmented_array_INCLUDED #ifndef symtab_INCLUDED #include "symtab.h" #endif // symtab_INCLUDED #ifndef wn_INCLUDED #include "wn.h" #endif // wn_INCLUDED #ifndef targ_sim_INCLUDED #include "targ_sim.h" #endif /* targ_sim_INCLUDED */ typedef mUINT32 BE_ST_IDX; // Definitions for BE_ST::flags const UINT32 BE_ST_ADDR_USED_LOCALLY = 0x00000001; // Address of item is taken somewhere const UINT32 BE_ST_ADDR_PASSED = 0x00000002; // Address of item is passed by ref const UINT32 BE_ST_W2FC_REFERENCED = 0x00000004; // whirl2{f,c} sees reference to ST const UINT32 BE_ST_UNKNOWN_CONST = 0x00000008; // Const, with unknown value // (Generated by LNO) // BE_ST_ADDR_ADDR_* bits are valid only if this is set const UINT32 BE_ST_PU_HAS_VALID_ADDR_FLAGS = 0x00000010; // ST_ADDR_* bits are no longer valid and need to be recomputed const UINT32 BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST = 0x00000020; // Back-end-specific information about each symtab entry class BE_ST { mUINT32 flags; void *io_auxst; public: BE_ST(void) : flags(0),io_auxst(NULL) { } BOOL Is_set(UINT32 f) const { return flags & f; } void Set_flag(UINT32 f) { flags |= f; } void Clear_flag(UINT32 f) { flags &= ~f; } void Set_io_auxst(void *v) { io_auxst = v; } void * Io_auxst(void) { return io_auxst; } }; typedef RELATED_SEGMENTED_ARRAY BE_ST_TAB; struct BE_SCOPE { BE_ST_TAB *be_st_tab; }; struct BE_SCOPE_TAB_BE_ST_TAB_ACCESS { BE_SCOPE_TAB_BE_ST_TAB_ACCESS(void) { } BE_ST_TAB *operator()(BE_SCOPE **be_scope_tab, SYMTAB_IDX level) { return (*be_scope_tab)[level].be_st_tab; } }; extern BE_SCOPE *Be_scope_tab; typedef TABLE_INDEXED_BY_LEVEL8_AND_INDEX24 BE_SYMBOL_TABLE; extern BE_SYMBOL_TABLE Be_symbol_table; inline BOOL BE_ST_addr_used_locally(const ST_IDX idx) { return Be_symbol_table[idx].Is_set(BE_ST_ADDR_USED_LOCALLY); } inline BOOL BE_ST_addr_used_locally(const BE_ST *const be_st) { return be_st->Is_set(BE_ST_ADDR_USED_LOCALLY); } inline BOOL BE_ST_addr_used_locally(const ST *const st) { return Be_symbol_table[ST_st_idx(st)].Is_set(BE_ST_ADDR_USED_LOCALLY); } inline void Set_BE_ST_addr_used_locally(const ST_IDX idx) { Be_symbol_table[idx].Set_flag(BE_ST_ADDR_USED_LOCALLY); } inline void Set_BE_ST_addr_used_locally(BE_ST *const be_st) { be_st->Set_flag(BE_ST_ADDR_USED_LOCALLY); } inline void Set_BE_ST_addr_used_locally(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Set_flag(BE_ST_ADDR_USED_LOCALLY); } inline void Clear_BE_ST_addr_used_locally(const ST_IDX idx) { Be_symbol_table[idx].Clear_flag(BE_ST_ADDR_USED_LOCALLY); } inline void Clear_BE_ST_addr_used_locally(BE_ST *const be_st) { be_st->Clear_flag(BE_ST_ADDR_USED_LOCALLY); } inline void Clear_BE_ST_addr_used_locally(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Clear_flag(BE_ST_ADDR_USED_LOCALLY); } inline void BE_ST_set_io_auxst(const ST_IDX idx, void *v) { Be_symbol_table[idx].Set_io_auxst(v); } inline void * BE_ST_io_auxst(const ST_IDX idx) { return Be_symbol_table[idx].Io_auxst(); } inline BOOL BE_ST_addr_passed(const ST_IDX idx) { return Be_symbol_table[idx].Is_set(BE_ST_ADDR_PASSED); } inline BOOL BE_ST_addr_passed(const BE_ST *const be_st) { return be_st->Is_set(BE_ST_ADDR_PASSED); } inline BOOL BE_ST_addr_passed(const ST *const st) { return Be_symbol_table[ST_st_idx(st)].Is_set(BE_ST_ADDR_PASSED); } inline void Set_BE_ST_addr_passed(const ST_IDX idx) { Be_symbol_table[idx].Set_flag(BE_ST_ADDR_PASSED); } inline void Set_BE_ST_addr_passed(BE_ST *const be_st) { be_st->Set_flag(BE_ST_ADDR_PASSED); } inline void Set_BE_ST_addr_passed(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Set_flag(BE_ST_ADDR_PASSED); } inline void Clear_BE_ST_addr_passed(const ST_IDX idx) { Be_symbol_table[idx].Clear_flag(BE_ST_ADDR_PASSED); } inline void Clear_BE_ST_addr_passed(BE_ST *const be_st) { be_st->Clear_flag(BE_ST_ADDR_PASSED); } inline void Clear_BE_ST_addr_passed(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Clear_flag(BE_ST_ADDR_PASSED); } inline BOOL BE_ST_w2fc_referenced(const ST_IDX idx) { return Be_symbol_table[idx].Is_set(BE_ST_W2FC_REFERENCED); } inline BOOL BE_ST_w2fc_referenced(const BE_ST *const be_st) { return be_st->Is_set(BE_ST_W2FC_REFERENCED); } inline BOOL BE_ST_w2fc_referenced(const ST *const st) { return Be_symbol_table[ST_st_idx(st)].Is_set(BE_ST_W2FC_REFERENCED); } inline void Set_BE_ST_w2fc_referenced(const ST_IDX idx) { Be_symbol_table[idx].Set_flag(BE_ST_W2FC_REFERENCED); } inline void Set_BE_ST_w2fc_referenced(BE_ST *const be_st) { be_st->Set_flag(BE_ST_W2FC_REFERENCED); } inline void Set_BE_ST_w2fc_referenced(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Set_flag(BE_ST_W2FC_REFERENCED); } inline void Clear_BE_ST_w2fc_referenced(BE_ST *const be_st) { be_st->Clear_flag(BE_ST_W2FC_REFERENCED); } inline void Clear_BE_ST_w2fc_referenced(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Clear_flag(BE_ST_W2FC_REFERENCED); } inline void Clear_BE_ST_w2fc_referenced(const ST_IDX idx) { Be_symbol_table[idx].Clear_flag(BE_ST_W2FC_REFERENCED); } inline BOOL BE_ST_unknown_const(const ST_IDX idx) { return Be_symbol_table[idx].Is_set(BE_ST_UNKNOWN_CONST); } inline BOOL BE_ST_unknown_const(const BE_ST *const be_st) { return be_st->Is_set(BE_ST_UNKNOWN_CONST); } inline BOOL BE_ST_unknown_const(const ST *const st) { return Be_symbol_table[ST_st_idx(st)].Is_set(BE_ST_UNKNOWN_CONST); } inline void Set_BE_ST_unknown_const(const ST_IDX idx) { Be_symbol_table[idx].Set_flag(BE_ST_UNKNOWN_CONST); } inline void Set_BE_ST_unknown_const(BE_ST *const be_st) { be_st->Set_flag(BE_ST_UNKNOWN_CONST); } inline void Set_BE_ST_unknown_const(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Set_flag(BE_ST_UNKNOWN_CONST); } inline void Clear_BE_ST_unknown_const(BE_ST *const be_st) { be_st->Clear_flag(BE_ST_UNKNOWN_CONST); } inline void Clear_BE_ST_unknown_const(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Clear_flag(BE_ST_UNKNOWN_CONST); } inline void Clear_BE_ST_unknown_const(const ST_IDX idx) { Be_symbol_table[idx].Clear_flag(BE_ST_UNKNOWN_CONST); } inline BOOL BE_ST_pu_has_valid_addr_flags(const ST_IDX idx) { return Be_symbol_table[idx].Is_set(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline BOOL BE_ST_pu_has_valid_addr_flags(const BE_ST *const be_st) { return be_st->Is_set(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline BOOL BE_ST_pu_has_valid_addr_flags(const ST *const st) { return Be_symbol_table[ST_st_idx(st)].Is_set(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline void Set_BE_ST_pu_has_valid_addr_flags(const ST_IDX idx) { Be_symbol_table[idx].Set_flag(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline void Set_BE_ST_pu_has_valid_addr_flags(BE_ST *const be_st) { be_st->Set_flag(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline void Set_BE_ST_pu_has_valid_addr_flags(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Set_flag(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline void Clear_BE_ST_pu_has_valid_addr_flags(BE_ST *const be_st) { be_st->Clear_flag(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline void Clear_BE_ST_pu_has_valid_addr_flags(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Clear_flag(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline void Clear_BE_ST_pu_has_valid_addr_flags(const ST_IDX idx) { Be_symbol_table[idx].Clear_flag(BE_ST_PU_HAS_VALID_ADDR_FLAGS); } inline BOOL BE_ST_pu_needs_addr_flag_adjust(const ST_IDX idx) { return Be_symbol_table[idx].Is_set(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline BOOL BE_ST_pu_needs_addr_flag_adjust(const BE_ST *const be_st) { return be_st->Is_set(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline BOOL BE_ST_pu_needs_addr_flag_adjust(const ST *const st) { return Be_symbol_table[ST_st_idx(st)].Is_set(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline void Set_BE_ST_pu_needs_addr_flag_adjust(const ST_IDX idx) { Be_symbol_table[idx].Set_flag(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline void Set_BE_ST_pu_needs_addr_flag_adjust(BE_ST *const be_st) { be_st->Set_flag(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline void Set_BE_ST_pu_needs_addr_flag_adjust(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Set_flag(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline void Clear_BE_ST_pu_needs_addr_flag_adjust(BE_ST *const be_st) { be_st->Clear_flag(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline void Clear_BE_ST_pu_needs_addr_flag_adjust(const ST *const st) { Be_symbol_table[ST_st_idx(st)].Clear_flag(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } inline void Clear_BE_ST_pu_needs_addr_flag_adjust(const ST_IDX idx) { Be_symbol_table[idx].Clear_flag(BE_ST_PU_NEEDS_ADDR_FLAG_ADJUST); } // // BE-ST related utilities // // Return TRUE iff the ST is known to be a constant initialized to // some value. extern BOOL ST_is_const_initialized(const ST *); // Return TRUE iff the ST is known to be a constant scalar initialized // to a value we can determine at compile time and return in the // argument tcon_copy. extern BOOL ST_is_const_initialized_scalar(const ST *, TCON &tcon_copy); // Return the INITV_IDX of the value of the ST if the ST is a const // initialized scalar and we can find the INITV. extern INITV_IDX ST_is_const_and_has_initv(const ST *); // Return the INITV_IDX of the value of the ST if st is a // initialized scalar and we can find the INITV. extern INITV_IDX ST_has_initv(const ST *); // Back-end-specific information about each PU class BE_PU { private: mUINT16 last_label; public: INT16 Last_label(void) const { return last_label; } }; class BE_PREG { private: WN *home_location; public: BE_PREG(void) : home_location(NULL) { } void Set_home_location(WN *wn) { home_location = wn; } WN *Home_location(void) const { return home_location; } }; typedef RELATED_SEGMENTED_ARRAY BE_PREG_TAB; extern BE_PREG_TAB Be_preg_tab; // Create_Preg for back end components that want to associate a // home location with each register. static inline PREG_NUM Create_Preg(TYPE_ID mtype, char *name, WN *home) { PREG_NUM retval = Create_Preg(mtype, name); Be_preg_tab[retval - Last_Dedicated_Preg_Offset].Set_home_location(home); return retval; } static inline WN * Preg_Home(PREG_NUM preg) { const UINT idx = preg - Last_Dedicated_Preg_Offset; return (idx < Be_preg_tab.Size()) ? Be_preg_tab[idx].Home_location() : NULL; } extern void BE_symtab_initialize_be_scopes(void); extern void BE_symtab_free_be_scopes(void); extern void BE_symtab_alloc_scope_level(const SYMTAB_IDX); #endif // be_symtab_INCLUDED