1 /*-------------------------------------------------------------------------
3 pcodeflow.c - post code generation flow analysis
5 Written By - Scott Dattalo scott@dattalo.com
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
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.
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.
21 -------------------------------------------------------------------------*/
25 The purpose of the code in this file is to analyze the flow of the
32 #include "common.h" // Include everything in the SDCC src directory
37 #include "pcoderegs.h"
38 #include "pcodeflow.h"
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.
47 This is really overkill...
50 static set *FlowTree=NULL;
52 void dbg_dumpFlowTree(set *FlowTree)
57 fprintf(stderr,"Flow Tree: \n");
59 for(segment = setFirstItem(FlowTree); segment; segment=setNextItem(FlowTree)) {
61 fprintf(stderr,"Segment:\n");
63 for(pcflow=PCFL(setFirstItem(segment)); pcflow; pcflow=PCFL(setNextItem(segment))) {
64 fprintf(stderr, " 0x%03x",pcflow->pc.seq);
74 /*-----------------------------------------------------------------*
75 * void BuildFlowSegment(set *segment, pCodeFlow *pcflow)
76 *-----------------------------------------------------------------*/
77 void BuildFlowSegment(set *segment, pCodeFlow *pcflow)
81 pCodeFlowLink *pcflowLink=NULL;
83 /* Add this flow to the set if it's not in there already */
84 if(isinSet(segment, pcflow)) {
85 addSetHead(&FlowTree, segment);
89 addSetHead(&segment, pcflow);
91 /* Continue to add contiguous flows */
93 while( pcflow->to && ((nNextFlow = elementsInSet(pcflow->to)) == 1)) {
94 pcflowLink = (pCodeFlowLink *)(setFirstItem(pcflow->to));
95 pcflow = pcflowLink->pcflow;
97 if(isinSet(segment, pcflow)) {
98 addSetIfnotP(&FlowTree, segment);
102 addSetIfnotP(&segment, pcflow);
106 /* Branch: for each branch, duplicate the set and recursively call */
107 if(pcflow->to && nNextFlow>=2) {
108 pCodeFlow *pcflow_to;
110 set *branch_segment=NULL;
112 pcflowLink = (pCodeFlowLink *)(setFirstItem(pcflow->to));
113 pcflow_to = pcflowLink->pcflow;
115 addSetIfnotP(&segment, pcflow);
117 pcflowLink = (pCodeFlowLink *)(setNextItem(pcflow->to));
121 branch_segment = setFromSet(segment);
122 BuildFlowSegment(setFromSet(segment),pcflowLink->pcflow);
123 pcflowLink = (pCodeFlowLink *)(setNextItem(pcflow->to));
126 /* add the first branch to this segment */
127 BuildFlowSegment(segment,pcflow_to);
131 addSetIfnotP(&FlowTree, segment);
136 /*-----------------------------------------------------------------*
137 * void BuildFlowTree(pBlock *pb)
138 *-----------------------------------------------------------------*/
139 void BuildFlowTree(pBlock *pb)
146 /* Start with the first flow object of this pBlock */
148 pcflow = PCFL(findNextpCode(pb->pcHead, PC_FLOW));
151 BuildFlowSegment(segment, pcflow);
153 pb->FlowTree = FlowTree;
155 dbg_dumpFlowTree(FlowTree);
159 void LinkFlow(pBlock *pb)
165 //fprintf(stderr,"linkflow \n");
167 for( pcflow = findNextpCode(pb->pcHead, PC_FLOW);
169 pcflow = findNextpCode(pcflow->next, PC_FLOW) ) {
172 fprintf(stderr, "LinkFlow - pcflow is not a flow object ");