Added pcodeflow.c - much of pcode.c will eventually get moved here.
[fw/sdcc] / src / pic / pcodeflow.c
1 /*-------------------------------------------------------------------------
2
3    pcodeflow.c - post code generation flow analysis
4
5    Written By -  Scott Dattalo scott@dattalo.com
6
7    This program is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21 -------------------------------------------------------------------------*/
22 /*
23   pcodeflow.c
24
25   The purpose of the code in this file is to analyze the flow of the
26   pCode.
27
28 */
29
30 #include <stdio.h>
31
32 #include "common.h"   // Include everything in the SDCC src directory
33 #include "newalloc.h"
34 #include "ralloc.h"
35 #include "device.h"
36 #include "pcode.h"
37 #include "pcoderegs.h"
38 #include "pcodeflow.h"
39
40 #if 0
41
42 /* 
43    In the section that follows, an exhaustive flow "tree" is built.
44    It's not a tree that's really built, but instead every possible
45    flow path is constructed. 
46
47    This is really overkill...
48 */
49
50 static set *FlowTree=NULL;
51
52 void dbg_dumpFlowTree(set *FlowTree)
53 {
54   set *segment;
55   pCodeFlow *pcflow;
56
57   fprintf(stderr,"Flow Tree: \n");
58
59   for(segment = setFirstItem(FlowTree); segment; segment=setNextItem(FlowTree)) {
60
61     fprintf(stderr,"Segment:\n");
62
63     for(pcflow=PCFL(setFirstItem(segment)); pcflow; pcflow=PCFL(setNextItem(segment))) {
64       fprintf(stderr, "  0x%03x",pcflow->pc.seq);
65     }
66     fprintf(stderr,"\n");
67   }
68
69 }
70
71
72
73
74 /*-----------------------------------------------------------------*
75  * void BuildFlowSegment(set *segment, pCodeFlow *pcflow)
76  *-----------------------------------------------------------------*/
77 void BuildFlowSegment(set *segment, pCodeFlow *pcflow)
78 {
79
80   int nNextFlow=0;
81   pCodeFlowLink *pcflowLink=NULL;
82
83   /* Add this flow to the set if it's not in there already */
84   if(isinSet(segment, pcflow)) {
85     addSetHead(&FlowTree, segment);
86     return;
87   }
88
89   addSetHead(&segment, pcflow);
90
91   /* Continue to add contiguous flows */
92
93   while( pcflow->to && ((nNextFlow = elementsInSet(pcflow->to)) == 1)) {
94     pcflowLink = (pCodeFlowLink *)(setFirstItem(pcflow->to));
95     pcflow = pcflowLink->pcflow;
96
97     if(isinSet(segment, pcflow)) {
98       addSetIfnotP(&FlowTree, segment);
99       return;
100     }
101
102     addSetIfnotP(&segment, pcflow);
103
104   }
105
106   /* Branch: for each branch, duplicate the set and recursively call */
107   if(pcflow->to && nNextFlow>=2) {
108     pCodeFlow *pcflow_to;
109
110     set *branch_segment=NULL;
111     
112     pcflowLink = (pCodeFlowLink *)(setFirstItem(pcflow->to));
113     pcflow_to = pcflowLink->pcflow;
114
115     addSetIfnotP(&segment, pcflow);
116
117     pcflowLink = (pCodeFlowLink *)(setNextItem(pcflow->to));
118
119     while(pcflowLink) {
120
121       branch_segment = setFromSet(segment);
122       BuildFlowSegment(setFromSet(segment),pcflowLink->pcflow);
123       pcflowLink = (pCodeFlowLink *)(setNextItem(pcflow->to));
124     }
125
126     /* add the first branch to this segment */
127     BuildFlowSegment(segment,pcflow_to);
128
129   }
130
131   addSetIfnotP(&FlowTree, segment);
132
133   /* done */
134 }
135
136 /*-----------------------------------------------------------------*
137  * void BuildFlowTree(pBlock *pb)
138  *-----------------------------------------------------------------*/
139 void BuildFlowTree(pBlock *pb)
140 {
141   pCodeFlow *pcflow;
142   set *segment;
143
144   FlowTree = newSet();
145
146   /* Start with the first flow object of this pBlock */
147
148   pcflow = PCFL(findNextpCode(pb->pcHead, PC_FLOW));
149
150   segment = newSet();
151   BuildFlowSegment(segment, pcflow);
152
153   pb->FlowTree = FlowTree;
154
155   dbg_dumpFlowTree(FlowTree);
156 }
157 #endif
158
159 void LinkFlow(pBlock *pb)
160 {
161   pCode *pc=NULL;
162   pCode *pcflow;
163   pCode *pct;
164
165   //fprintf(stderr,"linkflow \n");
166
167   for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); 
168        pcflow != NULL;
169        pcflow = findNextpCode(pcflow->next, PC_FLOW) ) {
170
171     if(!isPCFL(pcflow))
172       fprintf(stderr, "LinkFlow - pcflow is not a flow object ");
173
174
175   }
176 }