00001
00002
00003
00004
00005 #ifdef USE_PCH
00006 #include "opt_pch.h"
00007 #endif // USE_PCH
00008 #pragma hdrstop
00009
00010
00011 #include <sys/elf_whirl.h>
00012
00013 #include "defs.h"
00014 #include "config.h"
00015 #include "config_debug.h"
00016 #include "glob.h"
00017 #include "timing.h"
00018 #include "tracing.h"
00019 #include "opt_base.h"
00020
00021 #include "wn.h"
00022 #include "wn_util.h"
00023 #include "cxx_memory.h"
00024 #include "stab.h"
00025 #include "optimizer.h"
00026
00027 #include "opt_defs.h"
00028 #include "opt_config.h"
00029 #include "region_util.h"
00030 #include "region_main.h"
00031 #include "be_version.h"
00032 #include "opt_lab.h"
00033
00034 #define MAP_HASH_SIZE 20
00035
00036
00037
00038 LabelOpt::LabelOpt()
00039 {
00040 MEM_POOL_Initialize(&_label_mem_pool, "label_mem_pool", FALSE);
00041 MEM_POOL_Push(&_label_mem_pool);
00042
00043 _label_map = CXX_NEW(MAP(MAP_HASH_SIZE, &_label_mem_pool), &_label_mem_pool);
00044 }
00045
00046
00047
00048 LabelOpt::~LabelOpt()
00049 {
00050 MEM_POOL_Pop(&_label_mem_pool);
00051 MEM_POOL_Delete(&_label_mem_pool);
00052 }
00053
00054
00055
00056 void
00057 LabelOpt::Set_Mark(INT32 num)
00058 {
00059 _label_map->Add_map((POINTER)(INTPTR)num, (POINTER)TRUE);
00060 }
00061
00062
00063
00064
00065 BOOL LabelOpt::Get_Mark(INT32 num)
00066 {
00067 return (BOOL)((_label_map->Get_val((POINTER)(INTPTR)num)) != NULL);
00068 }
00069
00070
00071
00072
00073
00074 void
00075 LabelOpt:: Mark_Referenced_Labels(WN * wn)
00076 {
00077 FmtAssert(wn != NULL, ("cannot mark a null label"));
00078
00079 switch (WN_operator(wn)) {
00080 case OPR_FUNC_ENTRY:
00081 Mark_Referenced_Labels(WN_func_body(wn));
00082 break;
00083 case OPR_IF:
00084 Mark_Referenced_Labels(WN_kid(wn, 0));
00085 Mark_Referenced_Labels(WN_kid(wn, 1));
00086 Mark_Referenced_Labels(WN_kid(wn, 2));
00087 break;
00088 case OPR_DO_LOOP:
00089 Mark_Referenced_Labels(WN_kid(wn, 4));
00090 break;
00091 case OPR_WHILE_DO:
00092 case OPR_DO_WHILE:
00093 Mark_Referenced_Labels(WN_kid(wn, 1));
00094 break;
00095 case OPR_BLOCK:
00096 for (WN * stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt)) {
00097 Mark_Referenced_Labels(stmt);
00098 }
00099 break;
00100 case OPR_GOTO:
00101 case OPR_FALSEBR:
00102 case OPR_TRUEBR:
00103 Set_Mark(WN_label_number(wn));
00104 break;
00105 default:
00106 return;
00107 }
00108 }
00109
00110
00111
00112
00113
00114 void
00115 LabelOpt::Remove_Unmarked_Labels(WN * wn)
00116 {
00117 FmtAssert(wn != NULL, ("can remove a null label"));
00118 WN * nextstmt;
00119
00120 switch (WN_operator(wn)) {
00121 case OPR_FUNC_ENTRY:
00122 Remove_Unmarked_Labels(WN_func_body(wn));
00123 break;
00124 case OPR_IF:
00125 Remove_Unmarked_Labels(WN_kid(wn, 0));
00126 Remove_Unmarked_Labels(WN_kid(wn, 1));
00127 Remove_Unmarked_Labels(WN_kid(wn, 2));
00128 break;
00129 case OPR_DO_LOOP:
00130 Remove_Unmarked_Labels(WN_kid(wn, 4));
00131 break;
00132 case OPR_WHILE_DO:
00133 case OPR_DO_WHILE:
00134 Remove_Unmarked_Labels(WN_kid(wn, 1));
00135 break;
00136 case OPR_BLOCK:
00137 nextstmt = NULL;
00138 for (WN * stmt = WN_first(wn); stmt != NULL; stmt = nextstmt) {
00139 nextstmt = WN_next(stmt);
00140 if (WN_operator(stmt) == OPR_LABEL) {
00141 if (Get_Mark(WN_label_number(stmt)) == FALSE) {
00142 WN_DELETE_FromBlock(wn, stmt);
00143 }
00144 } else {
00145 Remove_Unmarked_Labels(stmt);
00146 }
00147 }
00148 break;
00149 default:
00150 return;
00151 }
00152 }
00153
00154
00155
00156 void
00157 LabelOpt::Remove_Unreferenced_Labels(WN * wn)
00158 {
00159 LabelOpt labelOpt;
00160 labelOpt.Mark_Referenced_Labels(wn);
00161 labelOpt.Remove_Unmarked_Labels(wn);
00162 }