C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

switchnode.cc

Go to the documentation of this file.
00001 // $Id: switchnode.cc,v 1.3 2003/08/07 23:13:13 pnav Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
00035 //
00036 // ----------------------------------------------------------------------
00037 
00038 #include "c_breeze.h"
00039 
00040 // --------------------------------------------------------------------
00041 // Constructors
00042 // --------------------------------------------------------------------
00043 
00044 switchNode::switchNode(exprNode * expr, stmtNode * stmt, const Coord coord)
00045   : selectionNode(Switch, expr, stmt, coord),
00046     _cases(),
00047     _has_default(false)
00048 {}
00049 
00050 // ------------------------------------------------------------
00051 //  Walker
00052 // ------------------------------------------------------------
00053 
00054 void switchNode::visit(Visitor * the_visitor) 
00055 {
00056   the_visitor->at_switch(this);
00057 }
00058 
00059 void switchNode::walk(Walker & the_walker)
00060 {
00061   Walker::Order ord = the_walker.order(); 
00062 
00063   if (ord == Walker::Preorder || ord == Walker::Both)
00064     the_walker.at_switch(this, Walker::Preorder);
00065 
00066   if (the_walker.depth() == Walker::Subtree) {
00067     // -- Visit the children 
00068 
00069     if (expr())
00070       expr()->walk(the_walker);
00071 
00072     if (stmt())
00073       stmt()->walk(the_walker);
00074   }
00075 
00076   if (ord == Walker::Postorder || ord == Walker::Both)
00077     the_walker.at_switch(this, Walker::Postorder);
00078 }
00079 
00080 // ------------------------------------------------------------
00081 //  Dataflow
00082 // ------------------------------------------------------------
00083 
00084 void switchNode::dataflow(FlowVal * v, FlowProblem & fp)
00085 {
00086   if (fp.forward()) {
00087     fp.flow_switch(v, this, FlowProblem::Entry);
00088 
00089     if (expr())
00090       if (fp.basicblocks()) {
00091         fp.flow_basicblock(v, expr(), FlowProblem::Entry);
00092         fp.flow_basicblock(v, expr(), FlowProblem::Exit);
00093       }
00094       else
00095         expr()->dataflow(v, fp);
00096     
00097     // -- at_top holds flow values needed at cases
00098 
00099     at_top()->meet_and_diff(v, fp);
00100 
00101     // -- If no default, then flow can fall through
00102 
00103     if (! has_default())
00104       at_exit()->meet_and_diff(v, fp);
00105 
00106     // -- Dataflow the cases (pushes break values into at_exit)
00107     // Note: control does not flow directly into switch body
00108 
00109     v->to_top();
00110 
00111     if (stmt())
00112       stmt()->dataflow(v, fp);
00113 
00114     // -- Get the flow values collected from breaks
00115 
00116     v->meet(at_exit());
00117 
00118     fp.flow_switch(v, this, FlowProblem::Exit);
00119   }
00120   else {
00121     fp.flow_switch(v, this, FlowProblem::Exit);
00122 
00123     // -- at_exit holds values needed by breaks
00124 
00125     at_exit()->meet_and_diff(v, fp);
00126 
00127     // -- If no default, then flow can fall through
00128 
00129     if (! has_default())
00130       at_top()->meet_and_diff(at_exit(), fp);
00131 
00132     // -- Dataflow the cases (push values in to at_top)
00133 
00134     if (stmt())
00135       stmt()->dataflow(v, fp);
00136 
00137     // -- Get the flow values collected from the cases
00138     // Note: control does not flow directly into switch body
00139 
00140     v->to_top();
00141     v->meet(at_top());
00142 
00143     if (expr())
00144       if (fp.basicblocks()) {
00145         fp.flow_basicblock(v, expr(), FlowProblem::Exit);
00146         fp.flow_basicblock(v, expr(), FlowProblem::Entry);
00147       }
00148       else
00149         expr()->dataflow(v, fp);
00150 
00151     fp.flow_switch(v, this, FlowProblem::Entry);
00152   }
00153 }
00154 
00155 // ------------------------------------------------------------
00156 // Output
00157 // ------------------------------------------------------------
00158 
00159 void switchNode::output_stmt(output_context & ct, Node * parent)
00160 {
00161   ct << "switch " << '(';
00162 
00163   if (expr())
00164     expr()->output(ct, this);
00165 
00166   ct << ')';
00167   ct.space();
00168 
00169   if (stmt())
00170     stmt()->output(ct, this);
00171   else
00172     ct << ';';
00173 }
00174 
00175 // ------------------------------------------------------------
00176 //  Changer
00177 // ------------------------------------------------------------
00178 
00179 Node * switchNode::change(Changer & the_changer, bool redispatch)
00180 {
00181   Changer::Order ord = the_changer.order(); 
00182   switchNode * the_switch = this;
00183 
00184   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00185     the_switch = (switchNode *) the_changer.at_switch(the_switch, Changer::Preorder);
00186 
00187   if (the_switch) {
00188 
00189     if (the_switch != this)
00190       return the_switch->change(the_changer, true);
00191 
00192     exprNode * old_expr = the_switch->expr();
00193     if (old_expr) {
00194       exprNode * new_expr = (exprNode *) old_expr->change(the_changer);
00195       if (old_expr != new_expr) {
00196         //if (the_changer.delete_old())
00197           //delete old_expr;
00198         the_switch->expr(new_expr);
00199       }
00200     }
00201 
00202     blockNode * old_stmt = the_switch->stmt();
00203     if (old_stmt) {
00204       blockNode * new_stmt = (blockNode *) old_stmt->change(the_changer);
00205       if (old_stmt != new_stmt) {
00206         //if (the_changer.delete_old())
00207           //delete old_stmt;
00208         the_switch->stmt(new_stmt);
00209       }
00210     }
00211 
00212   }
00213 
00214   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00215     the_switch = (switchNode *) the_changer.at_switch(the_switch, Changer::Postorder);
00216 
00217   return the_switch;
00218 }
00219 
00220 
00221 // ------------------------------------------------------------
00222 // Destructor
00223 // ------------------------------------------------------------
00224 
00225 switchNode::~switchNode()
00226 {
00227 }

Generated on August 27, 2003
Back to the C-Breeze home page