cdg_cycle_detector.ccGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "cdg.h"
00015 #include "cdg_types.h"
00016
00017
00018
00019 bool cdg_self_loop(CDGNode* root){
00020 for (Iterator<CDElement> cdit=root->outs(); cdit.valid(); ++cdit){
00021 CDGNode* next=cdit.current().node();
00022 if (next==root){
00023 return true;
00024 }
00025 }
00026 return false;
00027 }
00028
00029
00030
00031 static int count_cycles;
00032
00033
00034 extern int _cdg_report_cycles;
00035
00036
00037 void dcc_dfs(CDGNode* root,ProgramUnit& pgm){
00038 root->visited(1);
00039 for (Iterator<CDElement> cdit=root->outs(); cdit.valid(); ++cdit){
00040 CDGNode* next=cdit.current().node();
00041
00042 if (!next->visited()) dcc_dfs(next,pgm);
00043 else{
00044 if (next->visited()==1){
00045
00046 if (next!=root) {
00047 if (_cdg_report_cycles){
00048 cout<<"\n\tDetected back edge in dfs traversal of CDG "
00049 <<"between statements "<<root->cfgnode()->tag()
00050 <<" and "<<next->cfgnode()->tag()
00051 <<" in program unit "<<pgm.routine_name_ref();
00052 }
00053 }
00054
00055
00056 if (next!=root){
00057 count_cycles++;
00058 }
00059 }
00060 }
00061 }
00062 root->visited(2);
00063 }
00064
00065
00066 int detect_cdg_cycles(ProgramUnit& pgm){
00067 count_cycles=0;
00068
00069 switch(pgm.pu_class()){
00070 case PROGRAM_PU_TYPE:
00071 case SUBROUTINE_PU_TYPE:
00072 case FUNCTION_PU_TYPE:
00073 break;
00074 default:
00075 p_warning("Input to detect_cdg_cycles is not a program, subroutine, or function: skipping.");
00076 return 0;
00077 }
00078
00079 CDGNode* root=pgm.stmts().first_ref()->cdgnode();
00080
00081 if (root==0){
00082 p_warning("CDG needs to be built before trying to find cycles in it.");
00083 return 0;
00084 }
00085
00086 clear_cdg_visited(pgm);
00087
00088 dcc_dfs(root,pgm);
00089
00090 return count_cycles;
00091 }
|