AliasAnalyser.h

Go to the documentation of this file.
00001 /*
00002  * Expression Template Matrix Library
00003  *
00004  * Copyright (C) 2004 - 2006 Ricky Lung <mtlung@users.sourceforge.net>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00030 #ifdef _MSC_VER
00031 #   pragma once
00032 #   pragma warning( push )
00033 #   pragma warning( disable : 4786 )
00034 #endif  // _MSC_VER
00035 
00036 #ifndef _EXMAT_ALIAS_ANALYSER_H
00037 #define _EXMAT_ALIAS_ANALYSER_H
00038 
00039 #include "ExpTree.h"
00040 
00041 namespace exmat {
00042 namespace PNS {
00043 
00045     template<class Exp>
00046     class GetAliasTmpType {
00047         enum {
00048             IsUnaExp = IsDerivedFrom<Exp,UnaExpTag>::RET,
00049             IsBinExp = IsDerivedFrom<Exp,BinExpTag>::RET,
00050             IsView = IsDerivedFrom<Exp,ViewTag>::RET,
00051             IsCon = !IsBinExp && !IsView
00052         };
00053         template<class Exp_>
00054         struct Identity {
00055             typedef Exp_ RET;
00056         };
00057         template<class Exp_>
00058         struct TmpHelper {
00059             typedef typename Exp_::temp_type RET;
00060         };
00061         typedef typename IF<
00062             IsCon,
00063             Identity<Exp>,
00064             TmpHelper<Exp>
00065         >::RET PreRET;
00066     public:
00067         typedef typename PreRET::RET RET;
00068     };
00069 
00071     template<class Exp>
00072     struct AliasAnalyser {
00073         enum {
00074             IsUnaExp = IsDerivedFrom<Exp,UnaExpTag>::RET,
00075             IsBinExp = IsDerivedFrom<Exp,BinExpTag>::RET,
00076             IsView = IsDerivedFrom<Exp,ViewTag>::RET,
00077             IsCon = !IsBinExp && !IsView
00078         };
00079 
00081         template<class T>
00082         struct Helper {
00083             typedef T left_type;
00084             typedef T right_type;
00085             typedef T inner_rep_type;
00086         };
00087 
00088         typedef typename IF<
00089             IsBinExp, Exp, Helper<Exp>
00090         >::RET exp_type;
00091 
00092         typedef typename IF<
00093             IsView, Exp, Helper<Exp>
00094         >::RET view_type;
00095 
00096         enum {
00098             IsLBinExpNode = IsDerivedFrom<typename exp_type::left_type,BinExpTag>::RET,
00100             IsRBinExpNode = IsDerivedFrom<typename exp_type::right_type,BinExpTag>::RET,
00102             IsLViewNode = IsDerivedFrom<typename exp_type::left_type,ViewTag>::RET,
00104             IsRViewNode = IsDerivedFrom<typename exp_type::right_type,ViewTag>::RET,
00106             IsLConNode = (!IsLBinExpNode && !IsLViewNode),
00108             IsRConNode = (!IsRBinExpNode && !IsRViewNode),
00110             IsViewConNode =
00111                 !IsDerivedFrom<typename view_type::inner_rep_type,ViewTag>::RET &&
00112                 !IsDerivedFrom<typename view_type::inner_rep_type,BinExpTag>::RET
00113         };
00114 
00116         template<class LType> EXMAT_INLINE2 static bool
00117         IsAliased(LType& l, const Exp& exp, const Int2Type<true>&, const bool IsNodePathLinear)
00118         {
00119             typedef typename exp_type::left_type lt;
00120             typedef typename exp_type::right_type rt;
00121 
00122             typedef typename IF<
00123                 IsLConNode, LeafeNode<NullTag>, AliasAnalyser<lt>
00124             >::RET left_child;
00125             typedef typename IF<
00126                 IsRConNode, LeafeNode<NullTag>, AliasAnalyser<rt>
00127             >::RET right_child;
00128 
00129             const bool LNP = IsNodePathLinear && exp_type::IsLinear;
00130             const bool la = left_child::IsAliased(l, exp.leftOp, LNP);
00131             const bool ra = right_child::IsAliased(l, exp.rightOp, LNP);
00132             return la || ra;
00133         }
00134 
00136         template<class LType> EXMAT_INLINE2 static bool
00137         IsAliased(LType& l, const Exp& exp, const Int2Type<false>&, const bool IsNodePathLinear)
00138         {
00139             typedef typename view_type::inner_rep_type vt;
00140             typedef typename IF<
00141                 IsViewConNode, LeafeNode<NullTag>, AliasAnalyser<vt>
00142             >::RET child;
00143 
00144             const bool LNP = IsNodePathLinear && Exp::IsLinear;
00145             return child::IsAliased(l, exp.rep, LNP);
00146         }
00147 
00148         template<class LType, class RType> EXMAT_INLINE2
00149         static bool IsAliased(LType& l, const RType& exp, const bool IsNodePathLinear=true) {
00150             return IsAliased(l, exp, Int2Type<IsBinExp>(), IsNodePathLinear);
00151         }
00152 
00153     };
00154 
00157     template<class LT, class RT> EXMAT_INLINE2
00158     bool IsAliased_Helper(LT& l, const RT& r, const Int2Type<true>& isCon) {
00159         return false;
00160     }
00161 
00163     template<class LT, class RT> EXMAT_INLINE2
00164     bool IsAliased_Helper(LT& l, const RT& r, const Int2Type<false>& isCon) {
00165         return AliasAnalyser<RT>::IsAliased(l, r);
00166     }
00167 
00168     template<class LT, class RT> EXMAT_INLINE2
00169     bool IsAliased(LT& l, const RT& r) {
00170         // If the left hand type is a non-linear view, always return true
00171         // It's not the idea solution, but since the use of left hand side view is rare
00172         if(IsDerivedFrom<LT,ViewTag>::RET && !LT::IsLinearRecursive)
00173             return true;
00174         enum {
00175             IsBinExp = IsDerivedFrom<RT,BinExpTag>::RET,
00176             IsView = IsDerivedFrom<RT,ViewTag>::RET,
00177             IsCon = (!IsBinExp && ! IsView),
00178             // If both the left and right hand side are linear operations, simple return false
00179             NoNeedAnalysis = IsCon || (LT::IsLinearRecursive && RT::IsLinearRecursive)
00180         };
00181         return IsAliased_Helper(l, r, Int2Type<NoNeedAnalysis>());
00182     }
00183 
00184 }   // namespace exmat
00185 }   // namespace exmat
00186 
00187 #if _MSC_VER
00188 #   pragma warning( pop )
00189 #endif  // EXMAT_VC
00190 
00191 #endif  // _EXMAT_ALIAS_ANALYSER_H

Generated on Sat May 6 23:11:54 2006 for Exmat by  doxygen 1.4.6-NO