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  

threeaddrnode.cc

Go to the documentation of this file.
00001 // $Id: threeaddrnode.cc,v 1.3 2003/08/07 23:13:15 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 //  Adam Brown
00013 // 
00014 //  Permission is hereby granted, free of charge, to any person
00015 //  obtaining a copy of this software and associated documentation
00016 //  files (the "Software"), to deal in the Software without
00017 //  restriction, including without limitation the rights to use, copy,
00018 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00019 //  of the Software, and to permit persons to whom the Software is
00020 //  furnished to do so, subject to the following conditions:
00021 //  
00022 //  The above copyright notice and this permission notice shall be
00023 //  included in all copies or substantial portions of the Software.
00024 //  
00025 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00026 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00027 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00028 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00029 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00030 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00031 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00032 //  THE SOFTWARE.
00033 //
00034 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00035 //  Computer Science for inspiring parts of the C-Breeze design.
00036 //
00037 // ----------------------------------------------------------------------
00038 
00039 #include "c_breeze.h"
00040 
00041 // ------------------------------------------------------------
00042 // Constructors
00043 // ------------------------------------------------------------
00044 
00045 threeAddrNode::threeAddrNode(operandNode * lhs, operandNode * rhs,
00046                              const Coord coord):
00047   stmtNode(ThreeAddr, coord),
00048   _lhs(lhs),
00049   _rhs1(rhs),
00050   _op(NULL),
00051   _rhs2(NULL),
00052   _sizeof_type(NULL)
00053 {
00054 }
00055 
00056 threeAddrNode::threeAddrNode(operandNode * lhs, unsigned int op_id, 
00057                              operandNode * rhs, const Coord coord):
00058   stmtNode(ThreeAddr, coord),
00059   _lhs(lhs),
00060   _rhs1(rhs),
00061   _op(Operators::table[op_id]),
00062   _rhs2(NULL),
00063   _sizeof_type(NULL)
00064 {
00065   // TODO: ensure that _op is a unary operator (!, ~, +, -)
00066 }
00067 
00068 threeAddrNode::threeAddrNode(operandNode * lhs, typeNode * type,
00069                              const Coord coord):
00070   stmtNode(ThreeAddr, coord),
00071   _lhs(lhs),
00072   _rhs1(NULL),
00073   _op(Operators::table[Operator::SIZEOF]),
00074   _rhs2(NULL),
00075   _sizeof_type(type)
00076 {
00077 }
00078 
00079 threeAddrNode::threeAddrNode(operandNode * lhs, operandNode * rhs1, 
00080                              unsigned int op_id, operandNode * rhs2, 
00081                              const Coord coord):
00082   stmtNode(ThreeAddr, coord),
00083   _lhs(lhs),
00084   _rhs1(rhs1),
00085   _op(Operators::table[op_id]),
00086   _rhs2(rhs2)
00087 {
00088   // TODO: ensure that _op is a non-control flow binary.  only arithmetic?
00089 }
00090 
00091 threeAddrNode::threeAddrNode(operandNode * lhs, operandNode * func, 
00092                              operand_list * arg_list, const Coord coord):
00093   stmtNode(ThreeAddr, coord),
00094   _lhs(lhs),
00095   _rhs1(func),
00096   _op(Operators::table[Operator::FUNC_CALL]),
00097   _rhs2(NULL)
00098 {
00099   if ( arg_list )
00100     _arg_list.swap(*arg_list);
00101 }
00102 
00103 threeAddrNode::threeAddrNode(operandNode * func, operand_list * arg_list, 
00104                              const Coord coord):
00105   stmtNode(ThreeAddr, coord),
00106   _lhs(NULL),
00107   _rhs1(func),
00108   _op(Operators::table[Operator::FUNC_CALL]),
00109   _rhs2(NULL)
00110 {
00111   if ( arg_list )
00112     _arg_list.swap(*arg_list);
00113 }
00114 
00115 // ------------------------------------------------------------
00116 // Walker
00117 // ------------------------------------------------------------
00118 
00119 void threeAddrNode::visit(Visitor * the_visitor)
00120 {
00121   the_visitor->at_threeAddr(this);
00122 }
00123 
00124 void threeAddrNode::walk(Walker & the_walker)
00125 {
00126   Walker::Order ord = the_walker.order();
00127 
00128   if ( ord == Walker::Preorder || ord == Walker::Both )
00129     the_walker.at_threeAddr(this, Walker::Preorder);
00130 
00131   if ( the_walker.depth() == Walker::Subtree ) {
00132     // -- Visit the children
00133     if ( lhs() )
00134       lhs()->walk(the_walker);
00135 
00136     if ( rhs1() )
00137       rhs1()->walk(the_walker);
00138 
00139     if ( rhs2() )
00140       rhs2()->walk(the_walker);
00141 
00142     if ( sizeof_type() )
00143       sizeof_type()->walk(the_walker);
00144 
00145     list_walker(arg_list(), the_walker);
00146   }
00147 
00148   if ( ord == Walker::Postorder || ord == Walker::Both )
00149     the_walker.at_threeAddr(this, Walker::Postorder);
00150 }
00151 
00152 // ------------------------------------------------------------
00153 // Changer
00154 // ------------------------------------------------------------
00155 
00156 Node * threeAddrNode::change(Changer & the_changer, bool redispatch)
00157 {
00158   Changer::Order ord = the_changer.order();
00159   threeAddrNode * the_3addr = this;
00160 
00161   if ( ( ord == Changer::Preorder || ord == Changer::Both ) && !redispatch )
00162     the_3addr = (threeAddrNode *) the_changer.at_threeAddr(the_3addr,
00163                                                            Changer::Preorder);
00164 
00165   if ( the_3addr ) {
00166     if ( the_3addr != this )
00167       return the_3addr->change(the_changer, true);
00168 
00169     operandNode * old_lhs = the_3addr->lhs();
00170     if ( old_lhs ) {
00171       operandNode * new_lhs = (operandNode *) old_lhs->change(the_changer);
00172       if ( old_lhs != new_lhs )
00173         the_3addr->lhs(new_lhs);
00174     }
00175 
00176     operandNode * old_rhs1 = the_3addr->rhs1();
00177     if ( old_rhs1 ) {
00178       operandNode * new_rhs1 = (operandNode *) old_rhs1->change(the_changer);
00179       if ( old_rhs1 != new_rhs1 )
00180         the_3addr->rhs1(new_rhs1);
00181     }
00182 
00183     operandNode * old_rhs2 = the_3addr->rhs2();
00184     if ( old_rhs2 ) {
00185       operandNode * new_rhs2 = (operandNode *) old_rhs2->change(the_changer);
00186       if ( old_rhs2 != new_rhs2 )
00187         the_3addr->rhs2(new_rhs2);
00188     }
00189 
00190     typeNode * old_sizeof_type = the_3addr->sizeof_type();
00191     if ( old_sizeof_type ) {
00192       typeNode * new_sizeof_type = 
00193         (typeNode *) old_sizeof_type->change(the_changer);
00194       if ( new_sizeof_type != old_sizeof_type )
00195         the_3addr->sizeof_type(new_sizeof_type);
00196     }
00197 
00198     change_list(the_3addr->arg_list(), the_changer);
00199   }
00200 
00201   if ( ( ord == Changer::Postorder || ord == Changer::Both ) && !redispatch )
00202     the_3addr = (threeAddrNode *) the_changer.at_threeAddr(the_3addr,
00203                                                            Changer::Postorder);
00204 
00205   return the_3addr;
00206 }
00207 
00208 // ------------------------------------------------------------
00209 // Output
00210 // ------------------------------------------------------------
00211 
00212 void threeAddrNode::output_stmt(output_context & ct, Node * parent)
00213 {
00214   if ( lhs() ) {
00215     lhs()->output(ct, this);
00216     ct.space();
00217     ct << '=' ;
00218     ct.space();
00219   }
00220 
00221   if ( op() ) {
00222     if ( op()->id() == Operator::FUNC_CALL ) {
00223       rhs1()->output(ct, this);
00224       ct << '(' ;
00225       output_delim_list(arg_list(), ct, this, ',');
00226       ct << ')' ;
00227     } else if ( op()->id() == Operator::SIZEOF
00228                 && sizeof_type() ) {
00229       ct << op()->print();
00230       ct << '(';
00231       sizeof_type()->output(ct, this);
00232       ct << ')';
00233     } else if ( op()->is_unary() ) {
00234       ct << op()->print();
00235       ct.space();
00236       rhs1()->output(ct, this);
00237     } else {
00238       rhs1()->output(ct, this);
00239       ct.space();
00240       ct << op()->print();
00241       ct.space();
00242       rhs2()->output(ct, this);
00243     }
00244   } else 
00245     rhs1()->output(ct, this);
00246   
00247   ct << ';' ;
00248 }
00249 
00250 // ------------------------------------------------------------
00251 // Dataflow
00252 // ------------------------------------------------------------
00253 
00254 void threeAddrNode::dataflow(FlowVal * v, FlowProblem & fp)
00255 {
00256   // TODO:  uhhh, sam?
00257 }

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