00001 #pragma once 00002 00003 #include "rose.h" 00004 00005 namespace ssa_private 00006 { 00007 00011 struct DataflowCfgFilter 00012 { 00013 00019 bool operator() (CFGNode cfgn) const 00020 { 00021 SgNode *node = cfgn.getNode(); 00022 00023 switch (node->variantT()) 00024 { 00025 //For function calls, we only keep the last node. The function is actually called after all its parameters 00026 //are evaluated. 00027 case V_SgFunctionCallExp: 00028 return (cfgn == node->cfgForEnd()); 00029 00030 //For basic blocks and other "container" nodes, keep the node that appears before the contents are executed 00031 case V_SgBasicBlock: 00032 case V_SgExprStatement: 00033 case V_SgCommaOpExp: 00034 return (cfgn == node->cfgForBeginning()); 00035 00036 //Keep the last index for initialized names. This way the def of the variable doesn't propagate to its assign 00037 //initializer. 00038 case V_SgInitializedName: 00039 return (cfgn == node->cfgForEnd()); 00040 00041 case V_SgTryStmt: 00042 return (cfgn == node->cfgForBeginning()); 00043 00044 //We only want the middle appearance of the teritatry operator - after its conditional expression 00045 //and before the true and false bodies. This makes it behave as an if statement for data flow 00046 //purposes 00047 case V_SgConditionalExp: 00048 return (cfgn.getIndex() == 1); 00049 00050 //Make these binary operators appear after their operands, because they are evaluated after their operands 00051 case V_SgAndOp: 00052 case V_SgOrOp: 00053 return (cfgn == node->cfgForEnd()); 00054 00055 default: 00056 return cfgn.isInteresting(); 00057 } 00058 } 00059 }; 00060 }
1.4.7